Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding principles for Python's design into 20 aphorisms, only 19 of which have been written down.
1
>>>import this
2
The Zen of Python, by Tim Peters
3
4
Beautiful is better than ugly.
5
Explicit is better than implicit.
6
Simple is better than complex.
7
Complex is better than complicated.
8
Flat is better than nested.
9
Sparse is better than dense.
10
Readability counts.
11
Special cases aren't special enough to break the rules.
12
Although practicality beats purity.
13
Errors should never pass silently.
14
Unless explicitly silenced.
15
In the face of ambiguity, refuse the temptation to guess.
16
There should be one--and preferably only one --obvious way to do it.
17
Although that way may not be obvious at first unless you're Dutch.
18
Now is better than never.
19
Although never is often better than *right* now.
20
If the implementation is hard to explain, it's a bad idea.
21
If the implementation is easy to explain, it may be a good idea.
22
Namespaces are one honking great idea -- let's do more of those!
Copied!
Return to the Top
Python Basics
Math Operators
From Highest to Lowest precedence:
Operators
Operation
Example
**
Exponent
2 ** 3 = 8
%
Modulus/Remainder
22 % 8 = 6
//
Integer division
22 // 8 = 2
/
Division
22 / 8 = 2.75
*
Multiplication
3 * 3 = 9
-
Subtraction
5 - 2 = 3
+
Addition
2 + 2 = 4
Examples of expressions in the interactive shell:
1
>>>2+3*6
2
20
Copied!
1
>>>(2+3)*6
2
30
Copied!
1
>>>2**8
2
256
Copied!
1
>>>23//7
2
3
Copied!
1
>>>23%7
2
2
Copied!
1
>>>(5-1)*((7+1)/(3-1))
2
16.0
Copied!
Return to the Top
Data Types
Data Type
Examples
Integers
-2, -1, 0, 1, 2, 3, 4, 5
Floating-point numbers
-1.25, -1.0, --0.5, 0.0, 0.5, 1.0, 1.25
Strings
'a', 'aa', 'aaa', 'Hello!', '11 cats'
Return to the Top
String Concatenation and Replication
String concatenation:
1
>>>'Alice''Bob'
2
'AliceBob'
Copied!
Note: Avoid + operator for string concatenation. Prefer string formatting.
String Replication:
1
>>>'Alice'*5
2
'AliceAliceAliceAliceAlice'
Copied!
Return to the Top
Variables
You can name a variable anything as long as it obeys the following rules:
1.
It can be only one word.
2.
It can use only letters, numbers, and the underscore (_) character.
3.
It can’t begin with a number.
4.
Variable name starting with an underscore (_) are considered as "unuseful`.
Example:
1
>>> spam ='Hello'
2
>>> spam
3
'Hello'
Copied!
1
>>> _spam ='Hello'
Copied!
_spam should not be used again in the code.
Return to the Top
Comments
Inline comment:
1
# This is a comment
Copied!
Multiline comment:
1
# This is a
2
# multiline comment
Copied!
Code with a comment:
1
a =1# initialization
Copied!
Please note the two spaces in front of the comment.
Function docstring:
1
deffoo():
2
"""
3
This is a function docstring
4
You can also use:
5
''' Function Docstring '''
6
"""
Copied!
Return to the Top
The print() Function
1
>>>print('Hello world!')
2
Hello world!
Copied!
1
>>> a =1
2
>>>print('Hello world!', a)
3
Hello world! 1
Copied!
Return to the Top
The input() Function
Example Code:
1
>>>print('What is your name?')# ask for their name
2
>>> myName =input()
3
>>>print('It is good to meet you, {}'.format(myName))
4
What is your name?
5
Al
6
It is good to meet you, Al
Copied!
Return to the Top
The len() Function
Evaluates to the integer value of the number of characters in a string:
1
>>>len('hello')
2
5
Copied!
Note: test of emptiness of strings, lists, dictionary, etc, should not use len, but prefer direct boolean evaluation.
1
>>> a =[1,2,3]
2
>>>if a:
3
>>>print("the list is not empty!")
Copied!
Return to the Top
The str(), int(), and float() Functions
Integer to String or Float:
1
>>>str(29)
2
'29'
Copied!
1
>>>print('I am {} years old.'.format(str(29)))
2
I am 29 years old.
Copied!
1
>>>str(-3.14)
2
'-3.14'
Copied!
Float to Integer:
1
>>>int(7.7)
2
7
Copied!
1
>>>int(7.7)+1
2
8
Copied!
Return to the Top
Flow Control
Comparison Operators
Operator
Meaning
==
Equal to
!=
Not equal to
<
Less than
>
Greater Than
<=
Less than or Equal to
>=
Greater than or Equal to
These operators evaluate to True or False depending on the values you give them.
Examples:
1
>>>42==42
2
True
Copied!
1
>>>40==42
2
False
Copied!
1
>>>'hello'=='hello'
2
True
Copied!
1
>>>'hello'=='Hello'
2
False
Copied!
1
>>>'dog'!='cat'
2
True
Copied!
1
>>>42==42.0
2
True
Copied!
1
>>>42=='42'
2
False
Copied!
Boolean evaluation
Never use == or != operator to evaluate boolean operation. Use the is or is not operators, or use implicit boolean evaluation.
NO (even if they are valid Python):
1
>>>True==True
2
True
Copied!
1
>>>True!=False
2
True
Copied!
YES (even if they are valid Python):
1
>>>TrueisTrue
2
True
Copied!
1
>>>TrueisnotFalse
2
True
Copied!
These statements are equivalent:
1
>>>if a isTrue:
2
>>>pass
3
>>>if a isnotFalse:
4
>>>pass
5
>>>if a:
6
>>>pass
Copied!
And these as well:
1
>>>if a isFalse:
2
>>>pass
3
>>>if a isnotTrue:
4
>>>pass
5
>>>ifnot a:
6
>>>pass
Copied!
Return to the Top
Boolean Operators
There are three Boolean operators: and, or, and not.
The and Operator’s Truth Table:
Expression
Evaluates to
True and True
True
True and False
False
False and True
False
False and False
False
The or Operator’s Truth Table:
Expression
Evaluates to
True or True
True
True or False
True
False or True
True
False or False
False
The not Operator’s Truth Table:
Expression
Evaluates to
not True
False
not False
True
Return to the Top
Mixing Boolean and Comparison Operators
1
>>>(4<5)and(5<6)
2
True
Copied!
1
>>>(4<5)and(9<6)
2
False
Copied!
1
>>>(1==2)or(2==2)
2
True
Copied!
You can also use multiple Boolean operators in an expression, along with the comparison operators:
1
>>>2+2==4andnot2+2==5and2*2==2+2
2
True
Copied!
Return to the Top
if Statements
1
if name =='Alice':
2
print('Hi, Alice.')
Copied!
Return to the Top
else Statements
1
name ='Bob'
2
if name =='Alice':
3
print('Hi, Alice.')
4
else:
5
print('Hello, stranger.')
Copied!
Return to the Top
elif Statements
1
name ='Bob'
2
age =5
3
if name =='Alice':
4
print('Hi, Alice.')
5
elif age <12:
6
print('You are not Alice, kiddo.')
Copied!
1
name ='Bob'
2
age =30
3
if name =='Alice':
4
print('Hi, Alice.')
5
elif age <12:
6
print('You are not Alice, kiddo.')
7
else:
8
print('You are neither Alice nor a little kid.')
Copied!
Return to the Top
while Loop Statements
1
spam =0
2
while spam <5:
3
print('Hello, world.')
4
spam = spam +1
Copied!
Return to the Top
break Statements
If the execution reaches a break statement, it immediately exits the while loop’s clause:
1
whileTrue:
2
print('Please type your name.')
3
name =input()
4
if name =='your name':
5
break
6
print('Thank you!')
Copied!
Return to the Top
continue Statements
When the program execution reaches a continue statement, the program execution immediately jumps back to the start of the loop.
1
whileTrue:
2
print('Who are you?')
3
name =input()
4
if name !='Joe':
5
continue
6
print('Hello, Joe. What is the password? (It is a fish.)')
7
password =input()
8
if password =='swordfish':
9
break
10
print('Access granted.')
Copied!
Return to the Top
for Loops and the range() Function
1
>>>print('My name is')
2
>>>for i inrange(5):
3
>>>print('Jimmy Five Times ({})'.format(str(i)))
4
My name is
5
Jimmy Five Times (0)
6
Jimmy Five Times (1)
7
Jimmy Five Times (2)
8
Jimmy Five Times (3)
9
Jimmy Five Times (4)
Copied!
The range() function can also be called with three arguments. The first two arguments will be the start and stop values, and the third will be the step argument. The step is the amount that the variable is increased by after each iteration.
1
>>>for i inrange(0,10,2):
2
>>>print(i)
3
0
4
2
5
4
6
6
7
8
Copied!
You can even use a negative number for the step argument to make the for loop count down instead of up.
1
>>>for i inrange(5,-1,-1):
2
>>>print(i)
3
5
4
4
5
3
6
2
7
1
8
0
Copied!
For else statement
This allows to specify a statement to execute in case of the full loop has been executed. Only useful when a break condition can occur in the loop:
1
>>>for i in[1,2,3,4,5]:
2
>>>if i ==3:
3
>>>break
4
>>>else:
5
>>>print("only executed when no item of the list is equal to 3")
Copied!
Return to the Top
Importing Modules
1
import random
2
for i inrange(5):
3
print(random.randint(1,10))
Copied!
1
import random, sys, os, math
Copied!
1
from random import*
Copied!
Return to the Top
Ending a Program Early with sys.exit()
1
import sys
2
3
whileTrue:
4
print('Type exit to exit.')
5
response =input()
6
if response =='exit':
7
sys.exit()
8
print('You typed {}.'.format(response))
Copied!
Return to the Top
Functions
1
>>>defhello(name):
2
>>>print('Hello {}'.format(name))
3
>>>
4
>>> hello('Alice')
5
>>> hello('Bob')
6
Hello Alice
7
Hello Bob
Copied!
Return to the Top
Return Values and return Statements
When creating a function using the def statement, you can specify what the return value should be with a return statement. A return statement consists of the following:
The return keyword.
The value or expression that the function should return.
1
import random
2
defgetAnswer(answerNumber):
3
if answerNumber ==1:
4
return'It is certain'
5
elif answerNumber ==2:
6
return'It is decidedly so'
7
elif answerNumber ==3:
8
return'Yes'
9
elif answerNumber ==4:
10
return'Reply hazy try again'
11
elif answerNumber ==5:
12
return'Ask again later'
13
elif answerNumber ==6:
14
return'Concentrate and ask again'
15
elif answerNumber ==7:
16
return'My reply is no'
17
elif answerNumber ==8:
18
return'Outlook not so good'
19
elif answerNumber ==9:
20
return'Very doubtful'
21
22
r = random.randint(1,9)
23
fortune = getAnswer(r)
24
print(fortune)
Copied!
Return to the Top
The None Value
1
>>> spam =print('Hello!')
2
Hello!
Copied!
1
>>> spam isNone
2
True
Copied!
Note: never compare to None with the == operator. Always use is.
Return to the Top
Keyword Arguments and print()
1
>>>print('Hello', end='')
2
>>>print('World')
3
HelloWorld
Copied!
1
>>>print('cats','dogs','mice')
2
cats dogs mice
Copied!
1
>>>print('cats','dogs','mice', sep=',')
2
cats,dogs,mice
Copied!
Return to the Top
Local and Global Scope
Code in the global scope cannot use any local variables.
However, a local scope can access global variables.
Code in a function’s local scope cannot use variables in any other local scope.
You can use the same name for different variables if they are in different scopes. That is, there can be a local variable named spam and a global variable also named spam.
Return to the Top
The global Statement
If you need to modify a global variable from within a function, use the global statement:
1
>>>defspam():
2
>>>global eggs
3
>>> eggs ='spam'
4
>>>
5
>>> eggs ='global'
6
>>> spam()
7
>>>print(eggs)
8
spam
Copied!
There are four rules to tell whether a variable is in a local scope or global scope:
1.
If a variable is being used in the global scope (that is, outside of all functions), then it is always a global variable.
2.
If there is a global statement for that variable in a function, it is a global variable.
3.
Otherwise, if the variable is used in an assignment statement in the function, it is a local variable.
4.
But if the variable is not used in an assignment statement, it is a global variable.
Return to the Top
Exception Handling
Basic exception handling
1
>>>defspam(divideBy):
2
>>>try:
3
>>>return42/ divideBy
4
>>>except ZeroDivisionError as e:
5
>>>print('Error: Invalid argument: {}'.format(e))
6
>>>
7
>>>print(spam(2))
8
>>>print(spam(12))
9
>>>print(spam(0))
10
>>>print(spam(1))
11
21.0
12
3.5
13
Error: Invalid argument: division by zero
14
None
15
42.0
Copied!
Return to the Top
Final code in exception handling
Code inside the finally section is always executed, no matter if an exception has been raised or not, and even if an exception is not caught.
1
>>>defspam(divideBy):
2
>>>try:
3
>>>return42/ divideBy
4
>>>except ZeroDivisionError as e:
5
>>>print('Error: Invalid argument: {}'.format(e))
6
>>>finally:
7
>>>print("-- division finished --")
8
>>>print(spam(2))
9
-- division finished --
10
21.0
11
>>>print(spam(12))
12
-- division finished --
13
3.5
14
>>>print(spam(0))
15
Error: Invalid Argument division by zero
16
-- division finished --
17
None
18
>>>print(spam(1))
19
-- division finished --
20
42.0
Copied!
Return to the Top
Lists
1
>>> spam =['cat','bat','rat','elephant']
2
3
>>> spam
4
['cat','bat','rat','elephant']
Copied!
Return to the Top
Getting Individual Values in a List with Indexes
1
>>> spam =['cat','bat','rat','elephant']
2
>>> spam[0]
3
'cat'
Copied!
1
>>> spam[1]
2
'bat'
Copied!
1
>>> spam[2]
2
'rat'
Copied!
1
>>> spam[3]
2
'elephant'
Copied!
Return to the Top
Negative Indexes
1
>>> spam =['cat','bat','rat','elephant']
2
>>> spam[-1]
3
'elephant'
Copied!
1
>>> spam[-3]
2
'bat'
Copied!
1
>>>'The {} is afraid of the {}.'.format(spam[-1], spam[-3])
>>>print('Index {} in supplies is: {}'.format(str(i), supply))
4
Index 0in supplies is: pens
5
Index 1in supplies is: staplers
6
Index 2in supplies is: flame-throwers
7
Index 3in supplies is: binders
Copied!
Return to the Top
Looping Through Multiple Lists with zip()
1
>>> name =['Pete','John','Elizabeth']
2
>>> age =[6,23,44]
3
>>>for n, a inzip(name, age):
4
>>>print('{} is {} years old'.format(n, a))
5
Pete is6 years old
6
John is23 years old
7
Elizabeth is44 years old
Copied!
The in and not in Operators
1
>>>'howdy'in['hello','hi','howdy','heyas']
2
True
Copied!
1
>>> spam =['hello','hi','howdy','heyas']
2
>>>'cat'in spam
3
False
Copied!
1
>>>'howdy'notin spam
2
False
Copied!
1
>>>'cat'notin spam
2
True
Copied!
Return to the Top
The Multiple Assignment Trick
The multiple assignment trick is a shortcut that lets you assign multiple variables with the values in a list in one line of code. So instead of doing this:
1
>>> cat =['fat','orange','loud']
2
3
>>> size = cat[0]
4
5
>>> color = cat[1]
6
7
>>> disposition = cat[2]
Copied!
You could type this line of code:
1
>>> cat =['fat','orange','loud']
2
3
>>> size, color, disposition = cat
Copied!
The multiple assignment trick can also be used to swap the values in two variables:
1
>>> a, b ='Alice','Bob'
2
>>> a, b = b, a
3
>>>print(a)
4
'Bob'
Copied!
1
>>>print(b)
2
'Alice'
Copied!
Return to the Top
Augmented Assignment Operators
Operator
Equivalent
spam += 1
spam = spam + 1
spam -= 1
spam = spam - 1
spam *= 1
spam = spam * 1
spam /= 1
spam = spam / 1
spam %= 1
spam = spam % 1
Examples:
1
>>> spam ='Hello'
2
>>> spam +=' world!'
3
>>> spam
4
'Hello world!'
5
6
>>> bacon =['Zophie']
7
>>> bacon *=3
8
>>> bacon
9
['Zophie','Zophie','Zophie']
Copied!
Return to the Top
Finding a Value in a List with the index() Method
1
>>> spam =['Zophie','Pooka','Fat-tail','Pooka']
2
3
>>> spam.index('Pooka')
4
1
Copied!
Return to the Top
Adding Values to Lists with the append() and insert() Methods
append():
1
>>> spam =['cat','dog','bat']
2
3
>>> spam.append('moose')
4
5
>>> spam
6
['cat','dog','bat','moose']
Copied!
insert():
1
>>> spam =['cat','dog','bat']
2
3
>>> spam.insert(1,'chicken')
4
5
>>> spam
6
['cat','chicken','dog','bat']
Copied!
Return to the Top
Removing Values from Lists with remove()
1
>>> spam =['cat','bat','rat','elephant']
2
3
>>> spam.remove('bat')
4
5
>>> spam
6
['cat','rat','elephant']
Copied!
If the value appears multiple times in the list, only the first instance of the value will be removed.
Return to the Top
Removing Values from Lists with pop()
1
>>> spam =['cat','bat','rat','elephant']
2
3
>>> spam.pop()
4
'elephant'
5
6
>>> spam
7
['cat','bat','rat']
8
9
>>> spam.pop(0)
10
'cat'
11
12
>>> spam
13
['bat','rat']
Copied!
Return to the Top
Sorting the Values in a List with the sort() Method
A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.
Initializing a set
There are two ways to create sets: using curly braces {} and the built-in function set()
1
>>> s ={1,2,3}
2
>>> s =set([1,2,3])
Copied!
When creating an empty set, be sure to not use the curly braces {} or you will get an empty dictionary instead.
1
>>> s ={}
2
>>>type(s)
3
<class'dict'>
Copied!
sets: unordered collections of unique elements
A set automatically remove all the duplicate values.
1
>>> s ={1,2,3,2,3,4}
2
>>> s
3
{1,2,3,4}
Copied!
And as an unordered data type, they can't be indexed.
1
>>> s ={1,2,3}
2
>>> s[0]
3
Traceback (most recent call last):
4
File "<stdin>", line 1,in<module>
5
TypeError:'set'object does not support indexing
6
>>>
Copied!
set add() and update()
Using the add() method we can add a single element to the set.
The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python.
The itertools module comes in the standard library and must be imported.
The operator module will also be used. This module is not necessary when using itertools, but needed for some of the examples below.
Return to the Top
accumulate()
Makes an iterator that returns the results of a function.
1
itertools.accumulate(iterable[, func])
Copied!
Example:
1
>>> data =[1,2,3,4,5]
2
>>> result = itertools.accumulate(data, operator.mul)
3
>>>for each in result:
4
>>>print(each)
5
1
6
2
7
6
8
24
9
120
Copied!
The operator.mul takes two numbers and multiplies them:
1
operator.mul(1,2)
2
2
3
operator.mul(2,3)
4
6
5
operator.mul(6,4)
6
24
7
operator.mul(24,5)
8
120
Copied!
Passing a function is optional:
1
>>> data =[5,2,6,4,5,9,1]
2
>>> result = itertools.accumulate(data)
3
>>>for each in result:
4
>>>print(each)
5
5
6
7
7
13
8
17
9
22
10
31
11
32
Copied!
If no function is designated the items will be summed:
1
5
2
5+2=7
3
7+6=13
4
13+4=17
5
17+5=22
6
22+9=31
7
31+1=32
Copied!
Return to the Top
combinations()
Takes an iterable and a integer. This will create all the unique combination that have r members.
1
itertools.combinations(iterable, r)
Copied!
Example:
1
>>> shapes =['circle','triangle','square',]
2
>>> result = itertools.combinations(shapes,2)
3
>>>for each in result:
4
>>>print(each)
5
('circle','triangle')
6
('circle','square')
7
('triangle','square')
Copied!
Return to the Top
combinations_with_replacement()
Just like combinations(), but allows individual elements to be repeated more than once.
Makes an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted.
>>>for each in itertools.zip_longest(colors, data, fillvalue=None):
4
>>>print(each)
5
('red',1)
6
('orange',2)
7
('yellow',3)
8
('green',4)
9
('blue',5)
10
(None,6)
11
(None,7)
12
(None,8)
13
(None,9)
14
(None,10)
Copied!
Return to the Top
Comprehensions
List comprehension
1
>>> a =[1,3,5,7,9,11]
2
3
>>>[i -1for i in a]
4
[0,2,4,6,8,10]
Copied!
Set comprehension
1
>>> b ={"abc","def"}
2
>>>{s.upper()for s in b}
3
{"ABC","DEF"}
Copied!
Dict comprehension
1
>>> c ={'name':'Pooka','age':5}
2
>>>{v: k for k, v in c.items()}
3
{'Pooka':'name',5:'age'}
Copied!
A List comprehension can be generated from a dictionary:
1
>>> c ={'name':'Pooka','first_name':'Oooka'}
2
>>>["{}:{}".format(k.upper(), v.upper())for k, v in c.items()]
3
['NAME:POOKA','FIRST_NAME:OOOKA']
Copied!
Manipulating Strings
Escape Characters
Escape character
Prints as
\'
Single quote
\"
Double quote
\t
Tab
\n
Newline (line break)
\\
Backslash
Example:
1
>>>print("Hello there!\nHow are you?\nI\'m doing fine.")
2
Hello there!
3
How are you?
4
I'm doing fine.
Copied!
Return to the Top
Raw Strings
A raw string completely ignores all escape characters and prints any backslash that appears in the string.
1
>>>print(r'That is Carol\'s cat.')
2
That is Carol\'s cat.
Copied!
Note: mostly used for regular expression definition (see re package)
Return to the Top
Multiline Strings with Triple Quotes
1
>>>print('''Dear Alice,
2
>>>
3
>>> Eve's cat has been arrested for catnapping, cat burglary, and extortion.
4
>>>
5
>>> Sincerely,
6
>>> Bob''')
7
Dear Alice,
8
9
Eve's cat has been arrested for catnapping, cat burglary,and extortion.
10
11
Sincerely,
12
Bob
Copied!
To keep a nicer flow in your code, you can use the dedent function from the textwrap standard package.
1
>>>from textwrap import dedent
2
>>>
3
>>>defmy_function():
4
>>>print('''
5
>>> Dear Alice,
6
>>>
7
>>> Eve's cat has been arrested for catnapping, cat burglary, and extortion.
8
>>>
9
>>> Sincerely,
10
>>> Bob
11
>>> ''').strip()
Copied!
This generates the same string than before.
Return to the Top
Indexing and Slicing Strings
1
H e l l o w o r l d !
2
0 1 2 3 4 5 6 7 8 9 10 11
Copied!
1
>>> spam ='Hello world!'
2
3
>>> spam[0]
4
'H'
Copied!
1
>>> spam[4]
2
'o'
Copied!
1
>>> spam[-1]
2
'!'
Copied!
Slicing:
1
>>> spam[0:5]
2
'Hello'
Copied!
1
>>> spam[:5]
2
'Hello'
Copied!
1
>>> spam[6:]
2
'world!'
Copied!
1
>>> spam[6:-1]
2
'world'
Copied!
1
>>> spam[:-1]
2
'Hello world'
Copied!
1
>>> spam[::-1]
2
'!dlrow olleH'
Copied!
1
>>> spam ='Hello world!'
2
>>> fizz = spam[0:5]
3
>>> fizz
4
'Hello'
Copied!
Return to the Top
The in and not in Operators with Strings
1
>>>'Hello'in'Hello World'
2
True
Copied!
1
>>>'Hello'in'Hello'
2
True
Copied!
1
>>>'HELLO'in'Hello World'
2
False
Copied!
1
>>>''in'spam'
2
True
Copied!
1
>>>'cats'notin'cats and dogs'
2
False
Copied!
The in and not in Operators with list
1
>>> a =[1,2,3,4]
2
>>>5in a
3
False
Copied!
1
>>>2in a
2
True
Copied!
Return to the Top
The upper(), lower(), isupper(), and islower() String Methods
upper() and lower():
1
>>> spam ='Hello world!'
2
>>> spam = spam.upper()
3
>>> spam
4
'HELLO WORLD!'
Copied!
1
>>> spam = spam.lower()
2
>>> spam
3
'hello world!'
Copied!
isupper() and islower():
1
>>> spam ='Hello world!'
2
>>> spam.islower()
3
False
Copied!
1
>>> spam.isupper()
2
False
Copied!
1
>>>'HELLO'.isupper()
2
True
Copied!
1
>>>'abc12345'.islower()
2
True
Copied!
1
>>>'12345'.islower()
2
False
Copied!
1
>>>'12345'.isupper()
2
False
Copied!
Return to the Top
The isX String Methods
isalpha() returns True if the string consists only of letters and is not blank.
isalnum() returns True if the string consists only of letters and numbers and is not blank.
isdecimal() returns True if the string consists only of numeric characters and is not blank.
isspace() returns True if the string consists only of spaces,tabs, and new-lines and is not blank.
istitle() returns True if the string consists only of words that begin with an uppercase letter followed by only lowercase letters.
Return to the Top
The startswith() and endswith() String Methods
1
>>>'Hello world!'.startswith('Hello')
2
True
Copied!
1
>>>'Hello world!'.endswith('world!')
2
True
Copied!
1
>>>'abc123'.startswith('abcdef')
2
False
Copied!
1
>>>'abc123'.endswith('12')
2
False
Copied!
1
>>>'Hello world!'.startswith('Hello world!')
2
True
Copied!
1
>>>'Hello world!'.endswith('Hello world!')
2
True
Copied!
Return to the Top
The join() and split() String Methods
join():
1
>>>', '.join(['cats','rats','bats'])
2
'cats, rats, bats'
Copied!
1
>>>' '.join(['My','name','is','Simon'])
2
'My name is Simon'
Copied!
1
>>>'ABC'.join(['My','name','is','Simon'])
2
'MyABCnameABCisABCSimon'
Copied!
split():
1
>>>'My name is Simon'.split()
2
['My','name','is','Simon']
Copied!
1
>>>'MyABCnameABCisABCSimon'.split('ABC')
2
['My','name','is','Simon']
Copied!
1
>>>'My name is Simon'.split('m')
2
['My na','e is Si','on']
Copied!
Return to the Top
Justifying Text with rjust(), ljust(), and center()
rjust() and ljust():
1
>>>'Hello'.rjust(10)
2
' Hello'
Copied!
1
>>>'Hello'.rjust(20)
2
' Hello'
Copied!
1
>>>'Hello World'.rjust(20)
2
' Hello World'
Copied!
1
>>>'Hello'.ljust(10)
2
'Hello '
Copied!
An optional second argument to rjust() and ljust() will specify a fill character other than a space character. Enter the following into the interactive shell:
1
>>>'Hello'.rjust(20,'*')
2
'***************Hello'
Copied!
1
>>>'Hello'.ljust(20,'-')
2
'Hello---------------'
Copied!
center():
1
>>>'Hello'.center(20)
2
' Hello '
Copied!
1
>>>'Hello'.center(20,'=')
2
'=======Hello========'
Copied!
Return to the Top
Removing Whitespace with strip(), rstrip(), and lstrip()
1
>>> spam =' Hello World '
2
>>> spam.strip()
3
'Hello World'
Copied!
1
>>> spam.lstrip()
2
'Hello World '
Copied!
1
>>> spam.rstrip()
2
' Hello World'
Copied!
1
>>> spam ='SpamSpamBaconSpamEggsSpamSpam'
2
>>> spam.strip('ampS')
3
'BaconSpamEggs'
Copied!
Return to the Top
Copying and Pasting Strings with the pyperclip Module (need pip install)
1
>>>import pyperclip
2
3
>>> pyperclip.copy('Hello world!')
4
5
>>> pyperclip.paste()
6
'Hello world!'
Copied!
Return to the Top
String Formatting
% operator
1
>>> name ='Pete'
2
>>>'Hello %s'% name
3
"Hello Pete"
Copied!
We can use the %x format specifier to convert an int value to a string:
1
>>> num =5
2
>>>'I have %x apples'% num
3
"I have 5 apples"
Copied!
Note: For new code, using str.format or f-strings (Python 3.6+) is strongly recommended over the % operator.
Return to the Top
String Formatting (str.format)
Python 3 introduced a new way to do string formatting that was later back-ported to Python 2.7. This makes the syntax for string formatting more regular.
1
>>> name ='John'
2
>>> age =20'
3
4
>>>"Hello I'm {}, my age is {}".format(name, age)
5
"Hello I'm John, my age is 20"
Copied!
1
>>>"Hello I'm {0}, my age is {1}".format(name, age)
The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals or the str.format() interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text.
Return to the Top
Lazy string formatting
You would only use %s string formatting on functions that can do lazy parameters evaluation, the most common being logging:
Prefer:
1
>>> name ="alice"
2
>>> logging.debug("User name: %s", name)
Copied!
Over:
1
>>> logging.debug("User name: {}".format(name))
Copied!
Or:
1
>>> logging.debug("User name: "+ name)
Copied!
Return to the Top
Formatted String Literals or f-strings (Python 3.6+)
1
>>> name ='Elizabeth'
2
>>>f'Hello {name}!'
3
'Hello Elizabeth!
Copied!
It is even possible to do inline arithmetic with it:
1
>>> a =5
2
>>> b =10
3
>>>f'Five plus ten is {a + b} and not {2*(a + b)}.'
4
'Five plus ten is 15 and not 30.'
Copied!
Return to the Top
Template Strings
A simpler and less powerful mechanism, but it is recommended when handling format strings generated by users. Due to their reduced complexity template strings are a safer choice.
1
>>>from string import Template
2
>>> name ='Elizabeth'
3
>>> t = Template('Hey $name!')
4
>>> t.substitute(name=name)
5
'Hey Elizabeth!'
Copied!
Return to the Top
Regular Expressions
1.
Import the regex module with import re.
2.
Create a Regex object with the re.compile() function. (Remember to use a raw string.)
3.
Pass the string you want to search into the Regex object’s search() method. This returns a Match object.
4.
Call the Match object’s group() method to return a string of the actual matched text.
All the regex functions in Python are in the re module:
>>> mo = phone_num_regex.search('My number is 415-555-4242.')
4
5
>>> mo.group(1)
6
'415'
7
8
>>> mo.group(2)
9
'555-4242'
10
11
>>> mo.group(0)
12
'415-555-4242'
13
14
>>> mo.group()
15
'415-555-4242'
Copied!
To retrieve all the groups at once: use the groups() method—note the plural form for the name.
1
>>> mo.groups()
2
('415','555-4242')
3
4
>>> area_code, main_number = mo.groups()
5
6
>>>print(area_code)
7
415
8
9
>>>print(main_number)
10
555-4242
Copied!
Return to the Top
Matching Multiple Groups with the Pipe
The | character is called a pipe. You can use it anywhere you want to match one of many expressions. For example, the regular expression r'Batman|Tina Fey' will match either 'Batman' or 'Tina Fey'.
1
>>> hero_regex = re.compile(r'Batman|Tina Fey')
2
3
>>> mo1 = hero_regex.search('Batman and Tina Fey.')
4
5
>>> mo1.group()
6
'Batman'
7
8
>>> mo2 = hero_regex.search('Tina Fey and Batman.')
9
10
>>> mo2.group()
11
'Tina Fey'
Copied!
You can also use the pipe to match one of several patterns as part of your regex:
>>> mo = bat_regex.search('Batmobile lost a wheel')
4
5
>>> mo.group()
6
'Batmobile'
7
8
>>> mo.group(1)
9
'mobile'
Copied!
Return to the Top
Optional Matching with the Question Mark
The ? character flags the group that precedes it as an optional part of the pattern.
1
>>> bat_regex = re.compile(r'Bat(wo)?man')
2
>>> mo1 = bat_regex.search('The Adventures of Batman')
3
>>> mo1.group()
4
'Batman'
5
6
>>> mo2 = bat_regex.search('The Adventures of Batwoman')
7
>>> mo2.group()
8
'Batwoman'
Copied!
Return to the Top
Matching Zero or More with the Star
The * (called the star or asterisk) means “match zero or more”—the group that precedes the star can occur any number of times in the text.
1
>>> bat_regex = re.compile(r'Bat(wo)*man')
2
>>> mo1 = bat_regex.search('The Adventures of Batman')
3
>>> mo1.group()
4
'Batman'
5
6
>>> mo2 = bat_regex.search('The Adventures of Batwoman')
7
>>> mo2.group()
8
'Batwoman'
9
10
>>> mo3 = bat_regex.search('The Adventures of Batwowowowoman')
11
>>> mo3.group()
12
'Batwowowowoman'
Copied!
Return to the Top
Matching One or More with the Plus
While * means “match zero or more,” the + (or plus) means “match one or more”. The group preceding a plus must appear at least once. It is not optional:
1
>>> bat_regex = re.compile(r'Bat(wo)+man')
2
>>> mo1 = bat_regex.search('The Adventures of Batwoman')
3
>>> mo1.group()
4
'Batwoman'
Copied!
1
>>> mo2 = bat_regex.search('The Adventures of Batwowowowoman')
2
>>> mo2.group()
3
'Batwowowowoman'
Copied!
1
>>> mo3 = bat_regex.search('The Adventures of Batman')
2
>>> mo3 isNone
3
True
Copied!
Return to the Top
Matching Specific Repetitions with Curly Brackets
If you have a group that you want to repeat a specific number of times, follow the group in your regex with a number in curly brackets. For example, the regex (Ha){3} will match the string 'HaHaHa', but it will not match 'HaHa', since the latter has only two repeats of the (Ha) group.
Instead of one number, you can specify a range by writing a minimum, a comma, and a maximum in between the curly brackets. For example, the regex (Ha){3,5} will match 'HaHaHa', 'HaHaHaHa', and 'HaHaHaHaHa'.
1
>>> ha_regex = re.compile(r'(Ha){3}')
2
>>> mo1 = ha_regex.search('HaHaHa')
3
>>> mo1.group()
4
'HaHaHa'
Copied!
1
>>> mo2 = ha_regex.search('Ha')
2
>>> mo2 isNone
3
True
Copied!
Return to the Top
Greedy and Nongreedy Matching
Python’s regular expressions are greedy by default, which means that in ambiguous situations they will match the longest string possible. The non-greedy version of the curly brackets, which matches the shortest string possible, has the closing curly bracket followed by a question mark.
In addition to the search() method, Regex objects also have a findall() method. While search() will return a Match object of the first matched text in the searched string, the findall() method will return the strings of every match in the searched string.
1
>>> phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')# has no groups
To summarize what the findall() method returns, remember the following:
When called on a regex with no groups, such as \d-\d\d\d-\d\d\d\d, the method findall() returns a list of ng matches, such as ['415-555-9999', '212-555-0000'].
When called on a regex that has groups, such as (\d\d\d)-(d\d)-(\d\d\d\d), the method findall() returns a list of es of strings (one string for each group), such as [('415', '555', '9999'), ('212', '555', '0000')].
Return to the Top
Making Your Own Character Classes
There are times when you want to match a set of characters but the shorthand character classes (\d, \w, \s, and so on) are too broad. You can define your own character class using square brackets. For example, the character class [aeiouAEIOU] will match any vowel, both lowercase and uppercase.
You can also include ranges of letters or numbers by using a hyphen. For example, the character class [a-zA-Z0-9] will match all lowercase letters, uppercase letters, and numbers.
By placing a caret character (^) just after the character class’s opening bracket, you can make a negative character class. A negative character class will match all the characters that are not in the character class. For example, enter the following into the interactive shell:
You can also use the caret symbol (^) at the start of a regex to indicate that a match must occur at the beginning of the searched text.
Likewise, you can put a dollar sign ($) at the end of the regex to indicate the string must end with this regex pattern.
And you can use the ^ and $ together to indicate that the entire string must match the regex—that is, it’s not enough for a match to be made on some subset of the string.
The r'^Hello' regular expression string matches strings that begin with 'Hello':
The . (or dot) character in a regular expression is called a wildcard and will match any character except for a newline:
1
>>> at_regex = re.compile(r'.at')
2
3
>>> at_regex.findall('The cat in the hat sat on the flat mat.')
4
['cat','hat','sat','lat','mat']
Copied!
Return to the Top
Matching Everything with Dot-Star
1
>>> name_regex = re.compile(r'First Name: (.*) Last Name: (.*)')
2
3
>>> mo = name_regex.search('First Name: Al Last Name: Sweigart')
4
5
>>> mo.group(1)
6
'Al'
Copied!
1
>>> mo.group(2)
2
'Sweigart'
Copied!
The dot-star uses greedy mode: It will always try to match as much text as possible. To match any and all text in a nongreedy fashion, use the dot, star, and question mark (.*?). The question mark tells Python to match in a nongreedy way:
1
>>> nongreedy_regex = re.compile(r'<.*?>')
2
>>> mo = nongreedy_regex.search('<To serve man> for dinner.>')
3
>>> mo.group()
4
'<To serve man>'
Copied!
1
>>> greedy_regex = re.compile(r'<.*>')
2
>>> mo = greedy_regex.search('<To serve man> for dinner.>')
3
>>> mo.group()
4
'<To serve man> for dinner.>'
Copied!
Return to the Top
Matching Newlines with the Dot Character
The dot-star will match everything except a newline. By passing re.DOTALL as the second argument to re.compile(), you can make the dot character match all characters, including the newline character:
1
>>> no_newline_regex = re.compile('.*')
2
>>> no_newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
3
'Serve the public trust.'
Copied!
1
>>> newline_regex = re.compile('.*', re.DOTALL)
2
>>> newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
3
'Serve the public trust.\nProtect the innocent.\nUphold the law.'
Copied!
Return to the Top
Review of Regex Symbols
Symbol
Matches
?
zero or one of the preceding group.
*
zero or more of the preceding group.
+
one or more of the preceding group.
{n}
exactly n of the preceding group.
{n,}
n or more of the preceding group.
{,m}
0 to m of the preceding group.
{n,m}
at least n and at most m of the preceding p.
{n,m}? or *? or +?
performs a nongreedy match of the preceding p.
^spam
means the string must begin with spam.
spam$
means the string must end with spam.
.
any character, except newline characters.
\d, \w, and \s
a digit, word, or space character, respectively.
\D, \W, and \S
anything except a digit, word, or space, respectively.
[abc]
any character between the brackets (such as a, b, ).
[^abc]
any character that isn’t between the brackets.
Return to the Top
Case-Insensitive Matching
To make your regex case-insensitive, you can pass re.IGNORECASE or re.I as a second argument to re.compile():
1
>>> robocop = re.compile(r'robocop', re.I)
2
3
>>> robocop.search('Robocop is part man, part machine, all cop.').group()
4
'Robocop'
Copied!
1
>>> robocop.search('ROBOCOP protects the innocent.').group()
2
'ROBOCOP'
Copied!
1
>>> robocop.search('Al, why does your programming book talk about robocop so much?').group()
2
'robocop'
Copied!
Return to the Top
Substituting Strings with the sub() Method
The sub() method for Regex objects is passed two arguments:
1.
The first argument is a string to replace any matches.
2.
The second is the string for the regular expression.
The sub() method returns a string with the substitutions applied:
1
>>> names_regex = re.compile(r'Agent \w+')
2
3
>>> names_regex.sub('CENSORED','Agent Alice gave the secret documents to Agent Bob.')
>>> agent_names_regex.sub(r'\1****','Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.')
4
A**** told C**** that E**** knew B**** was a double agent.'
Copied!
Return to the Top
Managing Complex Regexes
To tell the re.compile() function to ignore whitespace and comments inside the regular expression string, “verbose mode” can be enabled by passing the variable re.VERBOSE as the second argument to re.compile().
Now instead of a hard-to-read regular expression like this:
you can spread the regular expression over multiple lines with comments like this:
1
phone_regex = re.compile(r'''(
2
(\d{3}|\(\d{3}\))? # area code
3
(\s|-|\.)? # separator
4
\d{3} # first 3 digits
5
(\s|-|\.) # separator
6
\d{4} # last 4 digits
7
(\s*(ext|x|ext.)\s*\d{2,5})? # extension
8
)''', re.VERBOSE)
Copied!
Return to the Top
Handling File and Directory Paths
There are two main modules in Python that deals with path manipulation. One is the os.path module and the other is the pathlib module. The pathlib module was added in Python 3.4, offering an object-oriented way to handle file system paths.
Return to the Top
Backslash on Windows and Forward Slash on OS X and Linux
On Windows, paths are written using backslashes (\) as the separator between folder names. On Unix based operating system such as macOS, Linux, and BSDs, the forward slash (/) is used as the path separator. Joining paths can be a headache if your code needs to work on different platforms.
Fortunately, Python provides easy ways to handle this. We will showcase how to deal with this with both os.path.join and pathlib.Path.joinpath
pathlib also provides a shortcut to joinpath using the / operator:
1
>>>from pathlib import Path
2
3
>>>print(Path('usr')/'bin'/'spam')
4
usr/bin/spam
Copied!
Notice the path separator is different between Windows and Unix based operating system, that's why you want to use one of the above methods instead of adding strings together to join paths together.
Joining paths is helpful if you need to create different file paths under the same directory.
File "/usr/lib/python3.6/pathlib.py", line 1226,in mkdir
7
self._accessor.mkdir(self, mode)
8
File "/usr/lib/python3.6/pathlib.py", line 387,in wrapped
9
return strfunc(str(pathobj),*args)
10
FileNotFoundError:[Errno 2] No such fileor directory:'/home/asweigart/delicious/walnut/waffles'
Copied!
Oh no, we got a nasty error! The reason is that the 'delicious' directory does not exist, so we cannot make the 'walnut' and the 'waffles' directories under it. To fix this, do:
An absolute path, which always begins with the root folder
A relative path, which is relative to the program’s current working directory
There are also the dot (.) and dot-dot (..) folders. These are not real folders but special names that can be used in a path. A single period (“dot”) for a folder name is shorthand for “this directory.” Two periods (“dot-dot”) means “the parent folder.”
Return to the Top
Handling Absolute and Relative Paths
To see if a path is an absolute path:
Using os.path on *nix:
1
>>>import os
2
>>> os.path.isabs('/')
3
True
4
>>> os.path.isabs('..')
5
False
Copied!
Using pathlib on *nix:
1
>>>from pathlib import Path
2
>>> Path('/').is_absolute()
3
True
4
>>> Path('..').is_absolute()
5
False
Copied!
You can extract an absolute path with both os.path and pathlib
Using os.path on *nix:
1
>>>import os
2
>>> os.getcwd()
3
'/home/asweigart'
4
>>> os.path.abspath('..')
5
'/home'
Copied!
Using pathlib on *nix:
1
from pathlib import Path
2
print(Path.cwd())
3
/home/asweigart
4
print(Path('..').resolve())
5
/home
Copied!
You can get a relative path from a starting path to another path.
To find the total size of all the files in this directory:
WARNING: Directories themselves also have a size! So you might want to check for whether a path is a file or directory using the methods in the methods discussed in the above section!
Using os.path.getsize() and os.listdir() together on Windows:
1
>>>import os
2
>>> total_size =0
3
4
>>>for filename in os.listdir('C:\\Windows\\System32'):
pathlib provides a lot more functionality than the ones listed above, like getting file name, getting file extension, reading/writing a file without manually opening it, etc. Check out the official documentation if you want to know more!
Reading and Writing Files
The File Reading/Writing Process
To read/write to a file in Python, you will want to use the with statement, which will close the file for you after you are done.
Return to the Top
Opening and reading files with the open() function
>>># Alternatively, you can use the *readlines()* method to get a list of string values from the file, one string for each line of text:
7
8
>>>withopen('sonnet29.txt')as sonnet_file:
9
... sonnet_file.readlines()
10
[When,in disgrace with fortune and men's eyes,\n', ' I all alone beweep my
11
outcast state,\n', And trouble deaf heaven with my bootless cries,\n', And
12
look upon myself and curse my fate,']
13
14
>>># You can also iterate through the file line by line:
15
>>>withopen('sonnet29.txt')as sonnet_file:
16
...for line in sonnet_file:# note the new line character will be included in the line
17
...print(line, end='')
18
19
When,in disgrace with fortune and men's eyes,
20
I all alone beweep my outcast state,
21
And trouble deaf heaven with my bootless cries,
22
And look upon myself and curse my fate,
Copied!
Return to the Top
Writing to Files
1
>>>withopen('bacon.txt','w')as bacon_file:
2
... bacon_file.write('Hello world!\n')
3
13
4
5
>>>withopen('bacon.txt','a')as bacon_file:
6
... bacon_file.write('Bacon is not a vegetable.')
7
25
8
9
>>>withopen('bacon.txt')as bacon_file:
10
... content = bacon_file.read()
11
12
>>>print(content)
13
Hello world!
14
Bacon isnot a vegetable.
Copied!
Return to the Top
Saving Variables with the shelve Module
To save variables:
1
>>>import shelve
2
3
>>> cats =['Zophie','Pooka','Simon']
4
>>>with shelve.open('mydata')as shelf_file:
5
... shelf_file['cats']= cats
Copied!
To open and read variables:
1
>>>with shelve.open('mydata')as shelf_file:
2
...print(type(shelf_file))
3
...print(shelf_file['cats'])
4
<class'shelve.DbfilenameShelf'>
5
['Zophie','Pooka','Simon']
Copied!
Just like dictionaries, shelf values have keys() and values() methods that will return list-like values of the keys and values in the shelf. Since these methods return list-like values instead of true lists, you should pass them to the list() function to get them in list form.
1
>>>with shelve.open('mydata')as shelf_file:
2
...print(list(shelf_file.keys()))
3
...print(list(shelf_file.values()))
4
['cats']
5
[['Zophie','Pooka','Simon']]
Copied!
Return to the Top
Saving Variables with the pprint.pformat() Function
This code will create a new ZIP file named new.zip that has the compressed contents of spam.txt.
Return to the Top
JSON, YAML and configuration files
JSON
Open a JSON file with:
1
import json
2
withopen("filename.json","r")as f:
3
content = json.loads(f.read())
Copied!
Write a JSON file with:
1
import json
2
3
content ={"name":"Joe","age":20}
4
withopen("filename.json","w")as f:
5
f.write(json.dumps(content, indent=2))
Copied!
Return to the Top
YAML
Compared to JSON, YAML allows for much better human maintainability and gives you the option to add comments. It is a convenient choice for configuration files where humans will have to edit it.
There are two main libraries allowing to access to YAML files:
Install them using pip install in your virtual environment.
The first one it easier to use but the second one, Ruamel, implements much better the YAML specification, and allow for example to modify a YAML content without altering comments.
Open a YAML file with:
1
from ruamel.yaml import YAML
2
3
withopen("filename.yaml")as f:
4
yaml=YAML()
5
yaml.load(f)
Copied!
Return to the Top
Anyconfig
Anyconfig is a very handy package allowing to abstract completely the underlying configuration file format. It allows to load a Python dictionary from JSON, YAML, TOML, and so on.
Exceptions are raised with a raise statement. In code, a raise statement consists of the following:
The raise keyword
A call to the Exception() function
A string with a helpful error message passed to the Exception() function
1
>>>raise Exception('This is the error message.')
2
Traceback (most recent call last):
3
File "<pyshell#191>", line 1,in<module>
4
raise Exception('This is the error message.')
5
Exception: This is the error message.
Copied!
Often it’s the code that calls the function, not the function itself, that knows how to handle an exception. So you will commonly see a raise statement inside a function and the try and except statements in the code calling the function.
1
defbox_print(symbol, width, height):
2
iflen(symbol)!=1:
3
raise Exception('Symbol must be a single character string.')
4
if width <=2:
5
raise Exception('Width must be greater than 2.')
6
if height <=2:
7
raise Exception('Height must be greater than 2.')
8
print(symbol * width)
9
for i inrange(height -2):
10
print(symbol +(' '*(width -2))+ symbol)
11
print(symbol * width)
12
for sym, w, h in(('*',4,4),('O',20,5),('x',1,3),('ZZ',3,3)):
13
try:
14
box_print(sym, w, h)
15
except Exception as err:
16
print('An exception happened: '+str(err))
Copied!
Return to the Top
Getting the Traceback as a String
The traceback is displayed by Python whenever a raised exception goes unhandled. But can also obtain it as a string by calling traceback.format_exc(). This function is useful if you want the information from an exception’s traceback but also want an except statement to gracefully handle the exception. You will need to import Python’s traceback module before calling this function.
1
>>>import traceback
2
3
>>>try:
4
>>>raise Exception('This is the error message.')
5
>>>except:
6
>>>withopen('errorInfo.txt','w')as error_file:
7
>>> error_file.write(traceback.format_exc())
8
>>>print('The traceback info was written to errorInfo.txt.')
9
116
10
The traceback info was written to errorInfo.txt.
Copied!
The 116 is the return value from the write() method, since 116 characters were written to the file. The traceback text was written to errorInfo.txt.
1
Traceback (most recent call last):
2
File "<pyshell#28>", line 2, in <module>
3
Exception: This is the error message.
Copied!
Return to the Top
Assertions
An assertion is a sanity check to make sure your code isn’t doing something obviously wrong. These sanity checks are performed by assert statements. If the sanity check fails, then an AssertionError exception is raised. In code, an assert statement consists of the following:
The assert keyword
A condition (that is, an expression that evaluates to True or False)
A comma
A string to display when the condition is False
1
>>> pod_bay_door_status ='open'
2
3
>>>assert pod_bay_door_status =='open','The pod bay doors need to be "open".'
4
5
>>> pod_bay_door_status ='I\'m sorry, Dave. I\'m afraid I can\'t do that.'
6
7
>>>assert pod_bay_door_status =='open','The pod bay doors need to be "open".'
8
9
Traceback (most recent call last):
10
File "<pyshell#10>", line 1,in<module>
11
assert pod_bay_door_status =='open','The pod bay doors need to be "open".'
12
AssertionError: The pod bay doors need to be "open".
Copied!
In plain English, an assert statement says, “I assert that this condition holds true, and if not, there is a bug somewhere in the program.” Unlike exceptions, your code should not handle assert statements with try and except; if an assert fails, your program should crash. By failing fast like this, you shorten the time between the original cause of the bug and when you first notice the bug. This will reduce the amount of code you will have to check before finding the code that’s causing the bug.
Disabling Assertions
Assertions can be disabled by passing the -O option when running Python.
Return to the Top
Logging
To enable the logging module to display log messages on your screen as your program runs, copy the following to the top of your program (but under the #! python shebang line):
Say you wrote a function to calculate the factorial of a number. In mathematics, factorial 4 is 1 × 2 × 3 × 4, or 24. Factorial 7 is 1 × 2 × 3 × 4 × 5 × 6 × 7, or 5,040. Open a new file editor window and enter the following code. It has a bug in it, but you will also enter several log messages to help yourself figure out what is going wrong. Save the program as factorialLog.py.
>>> logging.debug('i is '+str(i)+', total is '+str(total))
15
>>>
16
>>> logging.debug('End of factorial(%s)'%(n))
17
>>>
18
>>>return total
19
>>>
20
>>>print(factorial(5))
21
>>> logging.debug('End of program')
22
2015-05-2316:20:12,664- DEBUG - Start of program
23
2015-05-2316:20:12,664- DEBUG - Start of factorial(5)
24
2015-05-2316:20:12,665- DEBUG - i is0, total is0
25
2015-05-2316:20:12,668- DEBUG - i is1, total is0
26
2015-05-2316:20:12,670- DEBUG - i is2, total is0
27
2015-05-2316:20:12,673- DEBUG - i is3, total is0
28
2015-05-2316:20:12,675- DEBUG - i is4, total is0
29
2015-05-2316:20:12,678- DEBUG - i is5, total is0
30
2015-05-2316:20:12,680- DEBUG - End of factorial(5)
31
0
32
2015-05-2316:20:12,684- DEBUG - End of program
Copied!
Return to the Top
Logging Levels
Logging levels provide a way to categorize your log messages by importance. There are five logging levels, described in Table 10-1 from least to most important. Messages can be logged at each level using a different logging function.
Level
Logging Function
Description
DEBUG
logging.debug()
The lowest level. Used for small details. Usually you care about these messages only when diagnosing problems.
INFO
logging.info()
Used to record information on general events in your program or confirm that things are working at their point in the program.
WARNING
logging.warning()
Used to indicate a potential problem that doesn’t prevent the program from working but might do so in the future.
ERROR
logging.error()
Used to record an error that caused the program to fail to do something.
CRITICAL
logging.critical()
The highest level. Used to indicate a fatal error that has caused or is about to cause the program to stop running entirely.
Return to the Top
Disabling Logging
After you’ve debugged your program, you probably don’t want all these log messages cluttering the screen. The logging.disable() function disables these so that you don’t have to go into your program and remove all the logging calls by hand.
Instead of displaying the log messages to the screen, you can write them to a text file. The logging.basicConfig() function takes a filename keyword argument, like so:
It's not even need to bind it to a name like add before:
1
>>>(lambda x, y: x + y)(5,3)
2
8
Copied!
Like regular nested functions, lambdas also work as lexical closures:
1
>>>defmake_adder(n):
2
returnlambda x: x + n
3
4
>>> plus_3 = make_adder(3)
5
>>> plus_5 = make_adder(5)
6
7
>>> plus_3(4)
8
7
9
>>> plus_5(4)
10
9
Copied!
Note: lambda can only evaluate an expression, like a single line of code.
Return to the Top
Ternary Conditional Operator
Many programming languages have a ternary operator, which define a conditional expression. The most common usage is to make a terse simple conditional assignment statement. In other words, it offers one-line code to evaluate the first expression if the condition is true, otherwise it evaluates the second expression.
1
<expression1> if <condition> else <expression2>
Copied!
Example:
1
>>> age =15
2
3
>>>print('kid'if age <18else'adult')
4
kid
Copied!
Ternary operators can be chained:
1
>>> age =15
2
3
>>>print('kid'if age <13else'teenager'if age <18else'adult')
4
teenager
Copied!
The code above is equivalent to:
1
if age <18:
2
if age <13:
3
print('kid')
4
else:
5
print('teenager')
6
else:
7
print('adult')
Copied!
Return to the Top
args and kwargs
The names args and kwargs are arbitrary - the important thing are the * and ** operators. They can mean:
1.
In a function declaration, * means “pack all remaining positional arguments into a tuple named <name>”, while ** is the same for keyword arguments (except it uses a dictionary, not a tuple).
2.
In a function call, * means “unpack tuple or list named <name> to positional arguments at this position”, while ** is the same for keyword arguments.
For example you can make a function that you can use to call any other function, no matter what parameters it has:
1
defforward(f,*args,**kwargs):
2
return f(*args,**kwargs)
Copied!
Inside forward, args is a tuple (of all positional arguments except the first one, because we specified it - the f), kwargs is a dict. Then we call f and unpack them so they become normal arguments to f.
You use *args when you have an indefinite amount of positional arguments.
1
>>>deffruits(*args):
2
>>>for fruit in args:
3
>>>print(fruit)
4
5
>>> fruits("apples","bananas","grapes")
6
7
"apples"
8
"bananas"
9
"grapes"
Copied!
Similarly, you use **kwargs when you have an indefinite number of keyword arguments.
Functions can accept a variable number of positional arguments by using *args in the def statement.
2.
You can use the items from a sequence as the positional arguments for a function with the * operator.
3.
Using the * operator with a generator may cause your program to run out of memory and crash.
4.
Adding new positional parameters to functions that accept *args can introduce hard-to-find bugs.
Things to Remember(kwargs)
1.
Function arguments can be specified by position or by keyword.
2.
Keywords make it clear what the purpose of each argument is when it would be confusing with only positional arguments.
3.
Keyword arguments with default values make it easy to add new behaviors to a function, especially when the function has existing callers.
4.
Optional keyword arguments should always be passed by keyword instead of by position.
Return to the Top
Context Manager
While Python's context managers are widely used, few understand the purpose behind their use. These statements, commonly used with reading and writing files, assist the application in conserving system memory and improve resource management by ensuring specific resources are only in use for certain processes.
with statement
A context manager is an object that is notified when a context (a block of code) starts and ends. You commonly use one with the with statement. It takes care of the notifying.
For example, file objects are context managers. When a context ends, the file object is closed automatically:
1
>>>withopen(filename)as f:
2
>>> file_contents = f.read()
3
4
# the open_file object has automatically been closed.
Copied!
Anything that ends execution of the block causes the context manager's exit method to be called. This includes exceptions, and can be useful when an error causes you to prematurely exit from an open file or connection. Exiting a script without properly closing files/connections is a bad idea, that may cause data loss or other problems. By using a context manager you can ensure that precautions are always taken to prevent damage or loss in this way.
Writing your own contextmanager using generator syntax
It is also possible to write a context manager using generator syntax thanks to the contextlib.contextmanager decorator:
1
>>>import contextlib
2
>>> @contextlib.contextmanager
3
...defcontext_manager(num):
4
...print('Enter')
5
...yield num +1
6
...print('Exit')
7
>>>with context_manager(2)as cm:
8
...# the following instructions are run when the 'yield' point of the context
9
...# manager is reached.
10
...# 'cm' will have the value that was yielded
11
...print('Right in the middle with cm = {}'.format(cm))
12
Enter
13
Right in the middle with cm =3
14
Exit
15
16
>>>
Copied!
Return to the Top
__main__ Top-level script environment
__main__ is the name of the scope in which top-level code executes. A module’s name is set equal to __main__ when read from standard input, a script, or from an interactive prompt.
A module can discover whether or not it is running in the main scope by checking its own __name__, which allows a common idiom for conditionally executing code in a module when it is run as a script or with python -m but not when it is imported:
1
>>>if __name__ =="__main__":
2
...# execute only if run as a script
3
... main()
Copied!
For a package, the same effect can be achieved by including a main.py module, the contents of which will be executed when the module is run with -m
For example we are developing script which is designed to be used as module, we should do:
1
>>># Python program to execute function directly
2
>>>defadd(a, b):
3
...return a+b
4
...
5
>>> add(10,20)# we can test it by calling the function save it as calculate.py
6
30
7
>>># Now if we want to use that module by importing we have to comment out our call,
8
>>># Instead we can write like this in calculate.py
9
>>>if __name__ =="__main__":
10
... add(3,5)
11
...
12
>>>import calculate
13
>>> calculate.add(3,5)
14
8
Copied!
Advantages
1.
Every Python module has it’s __name__ defined and if this is __main__, it implies that the module is being run standalone by the user and we can do corresponding appropriate actions.
2.
If you import this script as a module in another script, the name is set to the name of the script/module.
3.
Python files can act as either reusable modules, or as standalone programs.
4.
if __name__ == “main”: is used to execute some code only if the file was run directly, and not imported.
Return to the Top
setup.py
The setup script is the centre of all activity in building, distributing, and installing modules using the Distutils. The main purpose of the setup script is to describe your module distribution to the Distutils, so that the various commands that operate on your modules do the right thing.
The setup.py file is at the heart of a Python project. It describes all of the metadata about your project. There a quite a few fields you can add to a project to give it a rich set of metadata describing the project. However, there are only three required fields: name, version, and packages. The name field must be unique if you wish to publish your package on the Python Package Index (PyPI). The version field keeps track of different releases of the project. The packages field describes where you’ve put the Python source code within your project.
This allows you to easily install Python packages. Often it's enough to write:
1
python setup.py install
Copied!
and module will install itself.
Our initial setup.py will also include information about the license and will re-use the README.txt file for the long_description field. This will look like:
Dataclasses are python classes but are suited for storing data objects. This module provides a decorator and functions for automatically adding generated special methods such as __init__() and __repr__() to user-defined classes.
Features
1.
They store data and represent a certain data type. Ex: A number. For people familiar with ORMs, a model instance is a data object. It represents a specific kind of entity. It holds attributes that define or represent the entity.
2.
They can be compared to other objects of the same type. Ex: A number can be greater than, less than, or equal to another number.
Python 3.7 provides a decorator dataclass that is used to convert a class into a dataclass.
python 2.7
1
>>>classNumber:
2
...def__init__(self, val):
3
... self.val = val
4
...
5
>>> obj = Number(2)
6
>>> obj.val
7
2
Copied!
with dataclass
1
>>> @dataclass
2
...classNumber:
3
... val:int
4
...
5
>>> obj = Number(2)
6
>>> obj.val
7
2
Copied!
Return to the Top
Default values
It is easy to add default values to the fields of your data class.
1
>>> @dataclass
2
...classProduct:
3
... name:str
4
... count:int=0
5
... price:float=0.0
6
...
7
>>> obj = Product("Python")
8
>>> obj.name
9
Python
10
>>> obj.count
11
0
12
>>> obj.price
13
0.0
Copied!
Type hints
It is mandatory to define the data type in dataclass. However, If you don't want specify the datatype then, use typing.Any.
1
>>>from dataclasses import dataclass
2
>>>from typing import Any
3
4
>>> @dataclass
5
...classWithoutExplicitTypes:
6
... name: Any
7
... value: Any =42
8
...
Copied!
Return to the Top
Virtual Environment
The use of a Virtual Environment is to test python code in encapsulated environments and to also avoid filling the base Python installation with libraries we might use for only one project.
Return to the Top
virtualenv
1.
Install virtualenv
1
pip install virtualenv
Copied!
2.
Install virtualenvwrapper-win (Windows)
1
pip install virtualenvwrapper-win
Copied!
Usage:
1.
Make a Virtual Environment
1
mkvirtualenv HelloWold
Copied!
Anything we install now will be specific to this project. And available to the projects we connect to this environment.
2.
Set Project Directory
To bind our virtualenv with our current working directory we simply enter:
1
setprojectdir .
Copied!
3.
Deactivate
To move onto something else in the command line type ‘deactivate’ to deactivate your environment.
1
deactivate
Copied!
Notice how the parenthesis disappear.
4.
Workon
Open up the command prompt and type ‘workon HelloWold’ to activate the environment and move into your root project folder
1
workon HelloWold
Copied!
Return to the Top
poetry
Poetry is a tool for dependency management and packaging in Python. It allows you to declare the libraries your project depends on and it will manage (install/update) them for you.
1.
Install Poetry
1
pip install --user poetry
Copied!
2.
Create a new project
1
poetry new my-project
Copied!
This will create a my-project directory:
1
my-project
2
├── pyproject.toml
3
├── README.rst
4
├── poetry_demo
5
│ └── __init__.py
6
└── tests
7
├── __init__.py
8
└── test_poetry_demo.py
Copied!
The pyproject.toml file will orchestrate your project and its dependencies:
Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. Windows is a first-class citizen, in our world.
1.
Install pipenv
1
pip install pipenv
Copied!
2.
Enter your Project directory and install the Packages for your project
1
cd my_project
2
pipenv install <package>
Copied!
Pipenv will install your package and create a Pipfile for you in your project’s directory. The Pipfile is used to track which dependencies your project needs in case you need to re-install them.
3.
Uninstall Packages
1
pipenv uninstall <package>
Copied!
4.
Activate the Virtual Environment associated with your Python project
From the [PEP 20 -- The Zen of Python](https://www.python.org/dev/peps/pep-0020/):
199
200
> Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding principles for Python's design into 20 aphorisms, only 19 of which have been written down.
201
202
```python
203
>>> import this
204
The Zen of Python, by Tim Peters
205
206
Beautiful is better than ugly.
207
Explicit is better than implicit.
208
Simple is better than complex.
209
Complex is better than complicated.
210
Flat is better than nested.
211
Sparse is better than dense.
212
Readability counts.
213
Special cases aren't special enough to break the rules.
214
Although practicality beats purity.
215
Errors should never pass silently.
216
Unless explicitly silenced.
217
In the face of ambiguity, refuse the temptation to guess.
218
There should be one-- and preferably only one --obvious way to do it.
219
Although that way may not be obvious at first unless you're Dutch.
220
Now is better than never.
221
Although never is often better than *right* now.
222
If the implementation is hard to explain, it's a bad idea.
223
If the implementation is easy to explain, it may be a good idea.
224
Namespaces are one honking great idea -- let's do more of those!
Note: Avoid `+` operator for string concatenation. Prefer string formatting.
299
300
String Replication:
301
302
```python
303
>>> 'Alice' * 5
304
'AliceAliceAliceAliceAlice'
305
```
306
307
[_Return to the Top_](#python-cheatsheet)
308
309
### Variables
310
311
You can name a variable anything as long as it obeys the following rules:
312
313
1. It can be only one word.
314
1. It can use only letters, numbers, and the underscore (`_`) character.
315
1. It can’t begin with a number.
316
1. Variable name starting with an underscore (`_`) are considered as "unuseful`.
317
318
Example:
319
320
```python
321
>>> spam = 'Hello'
322
>>> spam
323
'Hello'
324
```
325
326
```python
327
>>> _spam = 'Hello'
328
```
329
330
`_spam` should not be used again in the code.
331
332
[_Return to the Top_](#python-cheatsheet)
333
334
### Comments
335
336
Inline comment:
337
338
```python
339
# This is a comment
340
```
341
342
Multiline comment:
343
344
```Python
345
# This is a
346
# multiline comment
347
```
348
349
Code with a comment:
350
351
```python
352
a = 1 # initialization
353
```
354
355
Please note the two spaces in front of the comment.
356
357
Function docstring:
358
359
```python
360
def foo():
361
"""
362
This is a function docstring
363
You can also use:
364
''' Function Docstring '''
365
"""
366
```
367
368
[_Return to the Top_](#python-cheatsheet)
369
370
### The print() Function
371
372
```python
373
>>> print('Hello world!')
374
Hello world!
375
```
376
377
```python
378
>>> a = 1
379
>>> print('Hello world!', a)
380
Hello world! 1
381
```
382
383
[_Return to the Top_](#python-cheatsheet)
384
385
### The input() Function
386
387
Example Code:
388
389
```python
390
>>> print('What is your name?') # ask for their name
391
>>> myName = input()
392
>>> print('It is good to meet you, {}'.format(myName))
393
What is your name?
394
Al
395
It is good to meet you, Al
396
```
397
398
[_Return to the Top_](#python-cheatsheet)
399
400
### The len() Function
401
402
Evaluates to the integer value of the number of characters in a string:
403
404
```python
405
>>> len('hello')
406
5
407
```
408
409
Note: test of emptiness of strings, lists, dictionary, etc, should **not** use len, but prefer direct
410
boolean evaluation.
411
412
```python
413
>>> a = [1, 2, 3]
414
>>> if a:
415
>>> print("the list is not empty!")
416
```
417
418
[_Return to the Top_](#python-cheatsheet)
419
420
### The str(), int(), and float() Functions
421
422
Integer to String or Float:
423
424
```python
425
>>> str(29)
426
'29'
427
```
428
429
```python
430
>>> print('I am {} years old.'.format(str(29)))
431
I am 29 years old.
432
```
433
434
```python
435
>>> str(-3.14)
436
'-3.14'
437
```
438
439
Float to Integer:
440
441
```python
442
>>> int(7.7)
443
7
444
```
445
446
```python
447
>>> int(7.7) + 1
448
8
449
```
450
451
[_Return to the Top_](#python-cheatsheet)
452
453
## Flow Control
454
455
### Comparison Operators
456
457
| Operator | Meaning |
458
| -------- | ------------------------ |
459
| `==` | Equal to |
460
| `!=` | Not equal to |
461
| `<` | Less than |
462
| `>` | Greater Than |
463
| `<=` | Less than or Equal to |
464
| `>=` | Greater than or Equal to |
465
466
These operators evaluate to True or False depending on the values you give them.
467
468
Examples:
469
470
```python
471
>>> 42 == 42
472
True
473
```
474
475
```python
476
>>> 40 == 42
477
False
478
```
479
480
```python
481
>>> 'hello' == 'hello'
482
True
483
```
484
485
```python
486
>>> 'hello' == 'Hello'
487
False
488
```
489
490
```python
491
>>> 'dog' != 'cat'
492
True
493
```
494
495
```python
496
>>> 42 == 42.0
497
True
498
```
499
500
```python
501
>>> 42 == '42'
502
False
503
```
504
505
### Boolean evaluation
506
507
Never use `==` or `!=` operator to evaluate boolean operation. Use the `is` or `is not` operators,
508
or use implicit boolean evaluation.
509
510
NO (even if they are valid Python):
511
512
```python
513
>>> True == True
514
True
515
```
516
517
```python
518
>>> True != False
519
True
520
```
521
522
YES (even if they are valid Python):
523
524
```python
525
>>> True is True
526
True
527
```
528
529
```python
530
>>> True is not False
531
True
532
```
533
534
These statements are equivalent:
535
536
```Python
537
>>> if a is True:
538
>>> pass
539
>>> if a is not False:
540
>>> pass
541
>>> if a:
542
>>> pass
543
```
544
545
And these as well:
546
547
```Python
548
>>> if a is False:
549
>>> pass
550
>>> if a is not True:
551
>>> pass
552
>>> if not a:
553
>>> pass
554
```
555
556
[_Return to the Top_](#python-cheatsheet)
557
558
### Boolean Operators
559
560
There are three Boolean operators: and, or, and not.
561
562
The _and_ Operator’s _Truth_ Table:
563
564
| Expression | Evaluates to |
565
| ----------------- | ------------ |
566
| `True and True` | `True` |
567
| `True and False` | `False` |
568
| `False and True` | `False` |
569
| `False and False` | `False` |
570
571
The _or_ Operator’s _Truth_ Table:
572
573
| Expression | Evaluates to |
574
| ---------------- | ------------ |
575
| `True or True` | `True` |
576
| `True or False` | `True` |
577
| `False or True` | `True` |
578
| `False or False` | `False` |
579
580
The _not_ Operator’s _Truth_ Table:
581
582
| Expression | Evaluates to |
583
| ----------- | ------------ |
584
| `not True` | `False` |
585
| `not False` | `True` |
586
587
[_Return to the Top_](#python-cheatsheet)
588
589
### Mixing Boolean and Comparison Operators
590
591
```python
592
>>> (4 < 5) and (5 < 6)
593
True
594
```
595
596
```python
597
>>> (4 < 5) and (9 < 6)
598
False
599
```
600
601
```python
602
>>> (1 == 2) or (2 == 2)
603
True
604
```
605
606
You can also use multiple Boolean operators in an expression, along with the comparison operators:
607
608
```python
609
>>> 2 + 2 == 4 and not 2 + 2 == 5 and 2 * 2 == 2 + 2
610
True
611
```
612
613
[_Return to the Top_](#python-cheatsheet)
614
615
### if Statements
616
617
```python
618
if name == 'Alice':
619
print('Hi, Alice.')
620
```
621
622
[_Return to the Top_](#python-cheatsheet)
623
624
### else Statements
625
626
```python
627
name = 'Bob'
628
if name == 'Alice':
629
print('Hi, Alice.')
630
else:
631
print('Hello, stranger.')
632
```
633
634
[_Return to the Top_](#python-cheatsheet)
635
636
### elif Statements
637
638
```python
639
name = 'Bob'
640
age = 5
641
if name == 'Alice':
642
print('Hi, Alice.')
643
elif age < 12:
644
print('You are not Alice, kiddo.')
645
```
646
647
```python
648
name = 'Bob'
649
age = 30
650
if name == 'Alice':
651
print('Hi, Alice.')
652
elif age < 12:
653
print('You are not Alice, kiddo.')
654
else:
655
print('You are neither Alice nor a little kid.')
656
```
657
658
[_Return to the Top_](#python-cheatsheet)
659
660
### while Loop Statements
661
662
```python
663
spam = 0
664
while spam < 5:
665
print('Hello, world.')
666
spam = spam + 1
667
```
668
669
[_Return to the Top_](#python-cheatsheet)
670
671
### break Statements
672
673
If the execution reaches a break statement, it immediately exits the while loop’s clause:
674
675
```python
676
while True:
677
print('Please type your name.')
678
name = input()
679
if name == 'your name':
680
break
681
print('Thank you!')
682
```
683
684
[_Return to the Top_](#python-cheatsheet)
685
686
### continue Statements
687
688
When the program execution reaches a continue statement, the program execution immediately jumps back to the start of the loop.
689
690
```python
691
while True:
692
print('Who are you?')
693
name = input()
694
if name != 'Joe':
695
continue
696
print('Hello, Joe. What is the password? (It is a fish.)')
697
password = input()
698
if password == 'swordfish':
699
break
700
print('Access granted.')
701
```
702
703
[_Return to the Top_](#python-cheatsheet)
704
705
### for Loops and the range() Function
706
707
```python
708
>>> print('My name is')
709
>>> for i in range(5):
710
>>> print('Jimmy Five Times ({})'.format(str(i)))
711
My name is
712
Jimmy Five Times (0)
713
Jimmy Five Times (1)
714
Jimmy Five Times (2)
715
Jimmy Five Times (3)
716
Jimmy Five Times (4)
717
```
718
719
The _range()_ function can also be called with three arguments. The first two arguments will be the start and stop values, and the third will be the step argument. The step is the amount that the variable is increased by after each iteration.
720
721
```python
722
>>> for i in range(0, 10, 2):
723
>>> print(i)
724
0
725
2
726
4
727
6
728
8
729
```
730
731
You can even use a negative number for the step argument to make the for loop count down instead of up.
732
733
```python
734
>>> for i in range(5, -1, -1):
735
>>> print(i)
736
5
737
4
738
3
739
2
740
1
741
0
742
```
743
744
### For else statement
745
746
This allows to specify a statement to execute in case of the full loop has been executed. Only
747
useful when a `break` condition can occur in the loop:
748
749
```python
750
>>> for i in [1, 2, 3, 4, 5]:
751
>>> if i == 3:
752
>>> break
753
>>> else:
754
>>> print("only executed when no item of the list is equal to 3")
755
```
756
757
[_Return to the Top_](#python-cheatsheet)
758
759
### Importing Modules
760
761
```python
762
import random
763
for i in range(5):
764
print(random.randint(1, 10))
765
```
766
767
```python
768
import random, sys, os, math
769
```
770
771
```python
772
from random import *
773
```
774
775
[_Return to the Top_](#python-cheatsheet)
776
777
### Ending a Program Early with sys.exit()
778
779
```python
780
import sys
781
782
while True:
783
print('Type exit to exit.')
784
response = input()
785
if response == 'exit':
786
sys.exit()
787
print('You typed {}.'.format(response))
788
```
789
790
[_Return to the Top_](#python-cheatsheet)
791
792
## Functions
793
794
```python
795
>>> def hello(name):
796
>>> print('Hello {}'.format(name))
797
>>>
798
>>> hello('Alice')
799
>>> hello('Bob')
800
Hello Alice
801
Hello Bob
802
```
803
804
[_Return to the Top_](#python-cheatsheet)
805
806
### Return Values and return Statements
807
808
When creating a function using the def statement, you can specify what the return value should be with a return statement. A return statement consists of the following:
809
810
- The return keyword.
811
812
- The value or expression that the function should return.
813
814
```python
815
import random
816
def getAnswer(answerNumber):
817
if answerNumber == 1:
818
return 'It is certain'
819
elif answerNumber == 2:
820
return 'It is decidedly so'
821
elif answerNumber == 3:
822
return 'Yes'
823
elif answerNumber == 4:
824
return 'Reply hazy try again'
825
elif answerNumber == 5:
826
return 'Ask again later'
827
elif answerNumber == 6:
828
return 'Concentrate and ask again'
829
elif answerNumber == 7:
830
return 'My reply is no'
831
elif answerNumber == 8:
832
return 'Outlook not so good'
833
elif answerNumber == 9:
834
return 'Very doubtful'
835
836
r = random.randint(1, 9)
837
fortune = getAnswer(r)
838
print(fortune)
839
```
840
841
[_Return to the Top_](#python-cheatsheet)
842
843
### The None Value
844
845
```python
846
>>> spam = print('Hello!')
847
Hello!
848
```
849
850
```python
851
>>> spam is None
852
True
853
```
854
855
Note: never compare to `None` with the `==` operator. Always use `is`.
856
857
[_Return to the Top_](#python-cheatsheet)
858
859
### Keyword Arguments and print()
860
861
```python
862
>>> print('Hello', end='')
863
>>> print('World')
864
HelloWorld
865
```
866
867
```python
868
>>> print('cats', 'dogs', 'mice')
869
cats dogs mice
870
```
871
872
```python
873
>>> print('cats', 'dogs', 'mice', sep=',')
874
cats,dogs,mice
875
```
876
877
[_Return to the Top_](#python-cheatsheet)
878
879
### Local and Global Scope
880
881
- Code in the global scope cannot use any local variables.
882
883
- However, a local scope can access global variables.
884
885
- Code in a function’s local scope cannot use variables in any other local scope.
886
887
- You can use the same name for different variables if they are in different scopes. That is, there can be a local variable named spam and a global variable also named spam.
888
889
[_Return to the Top_](#python-cheatsheet)
890
891
### The global Statement
892
893
If you need to modify a global variable from within a function, use the global statement:
894
895
```python
896
>>> def spam():
897
>>> global eggs
898
>>> eggs = 'spam'
899
>>>
900
>>> eggs = 'global'
901
>>> spam()
902
>>> print(eggs)
903
spam
904
```
905
906
There are four rules to tell whether a variable is in a local scope or global scope:
907
908
1. If a variable is being used in the global scope (that is, outside of all functions), then it is always a global variable.
909
910
1. If there is a global statement for that variable in a function, it is a global variable.
911
912
1. Otherwise, if the variable is used in an assignment statement in the function, it is a local variable.
913
914
1. But if the variable is not used in an assignment statement, it is a global variable.
>>> print('Index {} in supplies is: {}'.format(str(i), supply))
1145
Index 0 in supplies is: pens
1146
Index 1 in supplies is: staplers
1147
Index 2 in supplies is: flame-throwers
1148
Index 3 in supplies is: binders
1149
```
1150
1151
[_Return to the Top_](#python-cheatsheet)
1152
1153
### Looping Through Multiple Lists with zip()
1154
1155
```python
1156
>>> name = ['Pete', 'John', 'Elizabeth']
1157
>>> age = [6, 23, 44]
1158
>>> for n, a in zip(name, age):
1159
>>> print('{} is {} years old'.format(n, a))
1160
Pete is 6 years old
1161
John is 23 years old
1162
Elizabeth is 44 years old
1163
```
1164
1165
### The in and not in Operators
1166
1167
```python
1168
>>> 'howdy' in ['hello', 'hi', 'howdy', 'heyas']
1169
True
1170
```
1171
1172
```python
1173
>>> spam = ['hello', 'hi', 'howdy', 'heyas']
1174
>>> 'cat' in spam
1175
False
1176
```
1177
1178
```python
1179
>>> 'howdy' not in spam
1180
False
1181
```
1182
1183
```python
1184
>>> 'cat' not in spam
1185
True
1186
```
1187
1188
[_Return to the Top_](#python-cheatsheet)
1189
1190
### The Multiple Assignment Trick
1191
1192
The multiple assignment trick is a shortcut that lets you assign multiple variables with the values in a list in one line of code. So instead of doing this:
1193
1194
```python
1195
>>> cat = ['fat', 'orange', 'loud']
1196
1197
>>> size = cat[0]
1198
1199
>>> color = cat[1]
1200
1201
>>> disposition = cat[2]
1202
```
1203
1204
You could type this line of code:
1205
1206
```python
1207
>>> cat = ['fat', 'orange', 'loud']
1208
1209
>>> size, color, disposition = cat
1210
```
1211
1212
The multiple assignment trick can also be used to swap the values in two variables:
1213
1214
```python
1215
>>> a, b = 'Alice', 'Bob'
1216
>>> a, b = b, a
1217
>>> print(a)
1218
'Bob'
1219
```
1220
1221
```python
1222
>>> print(b)
1223
'Alice'
1224
```
1225
1226
[_Return to the Top_](#python-cheatsheet)
1227
1228
### Augmented Assignment Operators
1229
1230
| Operator | Equivalent |
1231
| ----------- | ----------------- |
1232
| `spam += 1` | `spam = spam + 1` |
1233
| `spam -= 1` | `spam = spam - 1` |
1234
| `spam *= 1` | `spam = spam * 1` |
1235
| `spam /= 1` | `spam = spam / 1` |
1236
| `spam %= 1` | `spam = spam % 1` |
1237
1238
Examples:
1239
1240
```python
1241
>>> spam = 'Hello'
1242
>>> spam += ' world!'
1243
>>> spam
1244
'Hello world!'
1245
1246
>>> bacon = ['Zophie']
1247
>>> bacon *= 3
1248
>>> bacon
1249
['Zophie', 'Zophie', 'Zophie']
1250
```
1251
1252
[_Return to the Top_](#python-cheatsheet)
1253
1254
### Finding a Value in a List with the index() Method
Using the keys(), values(), and items() methods, a for loop can iterate over the keys, values, or key-value pairs in a dictionary, respectively.
1451
1452
```python
1453
1454
>>> spam = {'color': 'red', 'age': 42}
1455
>>>
1456
>>> for k, v in spam.items():
1457
>>> print('Key: {} Value: {}'.format(k, str(v)))
1458
Key: age Value: 42
1459
Key: color Value: red
1460
```
1461
1462
[_Return to the Top_](#python-cheatsheet)
1463
1464
### Checking Whether a Key or Value Exists in a Dictionary
1465
1466
```python
1467
>>> spam = {'name': 'Zophie', 'age': 7}
1468
```
1469
1470
```python
1471
>>> 'name' in spam.keys()
1472
True
1473
```
1474
1475
```python
1476
>>> 'Zophie' in spam.values()
1477
True
1478
```
1479
1480
```python
1481
>>> # You can omit the call to keys() when checking for a key
1482
>>> 'color' in spam
1483
False
1484
```
1485
1486
```python
1487
>>> 'color' not in spam
1488
True
1489
```
1490
1491
[_Return to the Top_](#python-cheatsheet)
1492
1493
### The get() Method
1494
1495
Get has two parameters: key and default value if the key did not exist
1496
1497
```python
1498
>>> picnic_items = {'apples': 5, 'cups': 2}
1499
1500
>>> 'I am bringing {} cups.'.format(str(picnic_items.get('cups', 0)))
1501
'I am bringing 2 cups.'
1502
```
1503
1504
```python
1505
>>> 'I am bringing {} eggs.'.format(str(picnic_items.get('eggs', 0)))
1506
'I am bringing 0 eggs.'
1507
```
1508
1509
[_Return to the Top_](#python-cheatsheet)
1510
1511
### The setdefault() Method
1512
1513
Let's consider this code:
1514
1515
```python
1516
spam = {'name': 'Pooka', 'age': 5}
1517
1518
if 'color' not in spam:
1519
spam['color'] = 'black'
1520
```
1521
1522
Using `setdefault` we could write the same code more succinctly:
1523
1524
```python
1525
>>> spam = {'name': 'Pooka', 'age': 5}
1526
>>> spam.setdefault('color', 'black')
1527
'black'
1528
```
1529
1530
```python
1531
>>> spam
1532
{'color': 'black', 'age': 5, 'name': 'Pooka'}
1533
```
1534
1535
```python
1536
>>> spam.setdefault('color', 'white')
1537
'black'
1538
```
1539
1540
```python
1541
>>> spam
1542
{'color': 'black', 'age': 5, 'name': 'Pooka'}
1543
```
1544
1545
[_Return to the Top_](#python-cheatsheet)
1546
1547
### Pretty Printing
1548
1549
```python
1550
>>> import pprint
1551
>>>
1552
>>> message = 'It was a bright cold day in April, and the clocks were striking
1553
>>> thirteen.'
1554
>>> count = {}
1555
>>>
1556
>>> for character in message:
1557
>>> count.setdefault(character, 0)
1558
>>> count[character] = count[character] + 1
1559
>>>
1560
>>> pprint.pprint(count)
1561
{' ': 13,
1562
',': 1,
1563
'.': 1,
1564
'A': 1,
1565
'I': 1,
1566
'a': 4,
1567
'b': 1,
1568
'c': 3,
1569
'd': 3,
1570
'e': 5,
1571
'g': 2,
1572
'h': 3,
1573
'i': 6,
1574
'k': 2,
1575
'l': 3,
1576
'n': 4,
1577
'o': 2,
1578
'p': 1,
1579
'r': 5,
1580
's': 3,
1581
't': 6,
1582
'w': 2,
1583
'y': 1}
1584
```
1585
1586
[_Return to the Top_](#python-cheatsheet)
1587
1588
### Merge two dictionaries
1589
1590
```python
1591
# in Python 3.5+:
1592
>>> x = {'a': 1, 'b': 2}
1593
>>> y = {'b': 3, 'c': 4}
1594
>>> z = {**x, **y}
1595
>>> z
1596
{'c': 4, 'a': 1, 'b': 3}
1597
1598
# in Python 2.7
1599
>>> z = dict(x, **y)
1600
>>> z
1601
{'c': 4, 'a': 1, 'b': 3}
1602
```
1603
1604
## sets
1605
1606
From the Python 3 [documentation](https://docs.python.org/3/tutorial/datastructures.html)
1607
1608
> A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.
1609
1610
### Initializing a set
1611
1612
There are two ways to create sets: using curly braces `{}` and the built-in function `set()`
1613
1614
```python
1615
>>> s = {1, 2, 3}
1616
>>> s = set([1, 2, 3])
1617
```
1618
1619
When creating an empty set, be sure to not use the curly braces `{}` or you will get an empty dictionary instead.
1620
1621
```python
1622
>>> s = {}
1623
>>> type(s)
1624
<class 'dict'>
1625
```
1626
1627
### sets: unordered collections of unique elements
1628
1629
A set automatically remove all the duplicate values.
1630
1631
```python
1632
>>> s = {1, 2, 3, 2, 3, 4}
1633
>>> s
1634
{1, 2, 3, 4}
1635
```
1636
1637
And as an unordered data type, they can't be indexed.
1638
1639
```python
1640
>>> s = {1, 2, 3}
1641
>>> s[0]
1642
Traceback (most recent call last):
1643
File "<stdin>", line 1, in <module>
1644
TypeError: 'set' object does not support indexing
1645
>>>
1646
```
1647
1648
### set add() and update()
1649
1650
Using the `add()` method we can add a single element to the set.
Both methods will remove an element from the set, but `remove()` will raise a `key error` if the value doesn't exist.
1671
1672
```python
1673
>>> s = {1, 2, 3}
1674
>>> s.remove(3)
1675
>>> s
1676
{1, 2}
1677
>>> s.remove(3)
1678
Traceback (most recent call last):
1679
File "<stdin>", line 1, in <module>
1680
KeyError: 3
1681
```
1682
1683
`discard()` won't raise any errors.
1684
1685
```python
1686
>>> s = {1, 2, 3}
1687
>>> s.discard(3)
1688
>>> s
1689
{1, 2}
1690
>>> s.discard(3)
1691
>>>
1692
```
1693
1694
### set union()
1695
1696
`union()` or `|` will create a new set that contains all the elements from the sets provided.
1697
1698
```python
1699
>>> s1 = {1, 2, 3}
1700
>>> s2 = {3, 4, 5}
1701
>>> s1.union(s2) # or 's1 | s2'
1702
{1, 2, 3, 4, 5}
1703
```
1704
1705
### set intersection
1706
1707
`intersection` or `&` will return a set containing only the elements that are common to all of them.
1708
1709
```python
1710
>>> s1 = {1, 2, 3}
1711
>>> s2 = {2, 3, 4}
1712
>>> s3 = {3, 4, 5}
1713
>>> s1.intersection(s2, s3) # or 's1 & s2 & s3'
1714
{3}
1715
```
1716
1717
### set difference
1718
1719
`difference` or `-` will return only the elements that are unique to the first set (invoked set).
1720
1721
```python
1722
>>> s1 = {1, 2, 3}
1723
>>> s2 = {2, 3, 4}
1724
>>> s1.difference(s2) # or 's1 - s2'
1725
{1}
1726
>>> s2.difference(s1) # or 's2 - s1'
1727
{4}
1728
```
1729
1730
### set symetric_difference
1731
1732
`symetric_difference` or `^` will return all the elements that are not common between them.
1733
1734
```python
1735
>>> s1 = {1, 2, 3}
1736
>>> s2 = {2, 3, 4}
1737
>>> s1.symmetric_difference(s2) # or 's1 ^ s2'
1738
{1, 4}
1739
```
1740
1741
[_Return to the Top_](#python-cheatsheet)
1742
1743
## itertools Module
1744
1745
The _itertools_ module is a collection of tools intended to be fast and use memory efficiently when handling iterators (like [lists](#lists) or [dictionaries](#dictionaries-and-structuring-data)).
1746
1747
From the official [Python 3.x documentation](https://docs.python.org/3/library/itertools.html):
1748
1749
> The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python.
1750
1751
The _itertools_ module comes in the standard library and must be imported.
1752
1753
The [operator](https://docs.python.org/3/library/operator.html) module will also be used. This module is not necessary when using itertools, but needed for some of the examples below.
1754
1755
[_Return to the Top_](#python-cheatsheet)
1756
1757
### accumulate()
1758
1759
Makes an iterator that returns the results of a function.
1760
1761
```python
1762
itertools.accumulate(iterable[, func])
1763
```
1764
1765
Example:
1766
1767
```python
1768
>>> data = [1, 2, 3, 4, 5]
1769
>>> result = itertools.accumulate(data, operator.mul)
1770
>>> for each in result:
1771
>>> print(each)
1772
1
1773
2
1774
6
1775
24
1776
120
1777
```
1778
1779
The operator.mul takes two numbers and multiplies them:
1780
1781
```python
1782
operator.mul(1, 2)
1783
2
1784
operator.mul(2, 3)
1785
6
1786
operator.mul(6, 4)
1787
24
1788
operator.mul(24, 5)
1789
120
1790
```
1791
1792
Passing a function is optional:
1793
1794
```python
1795
>>> data = [5, 2, 6, 4, 5, 9, 1]
1796
>>> result = itertools.accumulate(data)
1797
>>> for each in result:
1798
>>> print(each)
1799
5
1800
7
1801
13
1802
17
1803
22
1804
31
1805
32
1806
```
1807
1808
If no function is designated the items will be summed:
1809
1810
```python
1811
5
1812
5 + 2 = 7
1813
7 + 6 = 13
1814
13 + 4 = 17
1815
17 + 5 = 22
1816
22 + 9 = 31
1817
31 + 1 = 32
1818
```
1819
1820
[_Return to the Top_](#python-cheatsheet)
1821
1822
### combinations()
1823
1824
Takes an iterable and a integer. This will create all the unique combination that have r members.
1825
1826
```python
1827
itertools.combinations(iterable, r)
1828
```
1829
1830
Example:
1831
1832
```python
1833
>>> shapes = ['circle', 'triangle', 'square',]
1834
>>> result = itertools.combinations(shapes, 2)
1835
>>> for each in result:
1836
>>> print(each)
1837
('circle', 'triangle')
1838
('circle', 'square')
1839
('triangle', 'square')
1840
```
1841
1842
[_Return to the Top_](#python-cheatsheet)
1843
1844
### combinations_with_replacement()
1845
1846
Just like combinations(), but allows individual elements to be repeated more than once.
Makes an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted.
>>> for each in itertools.zip_longest(colors, data, fillvalue=None):
2250
>>> print(each)
2251
('red', 1)
2252
('orange', 2)
2253
('yellow', 3)
2254
('green', 4)
2255
('blue', 5)
2256
(None, 6)
2257
(None, 7)
2258
(None, 8)
2259
(None, 9)
2260
(None, 10)
2261
```
2262
2263
[_Return to the Top_](#python-cheatsheet)
2264
2265
## Comprehensions
2266
2267
### List comprehension
2268
2269
```python
2270
>>> a = [1, 3, 5, 7, 9, 11]
2271
2272
>>> [i - 1 for i in a]
2273
[0, 2, 4, 6, 8, 10]
2274
```
2275
2276
### Set comprehension
2277
2278
```python
2279
>>> b = {"abc", "def"}
2280
>>> {s.upper() for s in b}
2281
{"ABC", "DEF"}
2282
```
2283
2284
### Dict comprehension
2285
2286
```python
2287
>>> c = {'name': 'Pooka', 'age': 5}
2288
>>> {v: k for k, v in c.items()}
2289
{'Pooka': 'name', 5: 'age'}
2290
```
2291
2292
A List comprehension can be generated from a dictionary:
2293
2294
```python
2295
>>> c = {'name': 'Pooka', 'first_name': 'Oooka'}
2296
>>> ["{}:{}".format(k.upper(), v.upper()) for k, v in c.items()]
2297
['NAME:POOKA', 'FIRST_NAME:OOOKA']
2298
```
2299
2300
## Manipulating Strings
2301
2302
### Escape Characters
2303
2304
| Escape character | Prints as |
2305
| ---------------- | -------------------- |
2306
| `\'` | Single quote |
2307
| `\"` | Double quote |
2308
| `\t` | Tab |
2309
| `\n` | Newline (line break) |
2310
| `\\` | Backslash |
2311
2312
Example:
2313
2314
```python
2315
>>> print("Hello there!\nHow are you?\nI\'m doing fine.")
2316
Hello there!
2317
How are you?
2318
I'm doing fine.
2319
```
2320
2321
[_Return to the Top_](#python-cheatsheet)
2322
2323
### Raw Strings
2324
2325
A raw string completely ignores all escape characters and prints any backslash that appears in the string.
2326
2327
```python
2328
>>> print(r'That is Carol\'s cat.')
2329
That is Carol\'s cat.
2330
```
2331
2332
Note: mostly used for regular expression definition (see `re` package)
2333
2334
[_Return to the Top_](#python-cheatsheet)
2335
2336
### Multiline Strings with Triple Quotes
2337
2338
```python
2339
>>> print('''Dear Alice,
2340
>>>
2341
>>> Eve's cat has been arrested for catnapping, cat burglary, and extortion.
2342
>>>
2343
>>> Sincerely,
2344
>>> Bob''')
2345
Dear Alice,
2346
2347
Eve's cat has been arrested for catnapping, cat burglary, and extortion.
2348
2349
Sincerely,
2350
Bob
2351
```
2352
2353
To keep a nicer flow in your code, you can use the `dedent` function from the `textwrap` standard package.
2354
2355
```python
2356
>>> from textwrap import dedent
2357
>>>
2358
>>> def my_function():
2359
>>> print('''
2360
>>> Dear Alice,
2361
>>>
2362
>>> Eve's cat has been arrested for catnapping, cat burglary, and extortion.
2363
>>>
2364
>>> Sincerely,
2365
>>> Bob
2366
>>> ''').strip()
2367
```
2368
2369
This generates the same string than before.
2370
2371
[_Return to the Top_](#python-cheatsheet)
2372
2373
### Indexing and Slicing Strings
2374
2375
H e l l o w o r l d !
2376
0 1 2 3 4 5 6 7 8 9 10 11
2377
2378
```python
2379
>>> spam = 'Hello world!'
2380
2381
>>> spam[0]
2382
'H'
2383
```
2384
2385
```python
2386
>>> spam[4]
2387
'o'
2388
```
2389
2390
```python
2391
>>> spam[-1]
2392
'!'
2393
```
2394
2395
Slicing:
2396
2397
```python
2398
2399
>>> spam[0:5]
2400
'Hello'
2401
```
2402
2403
```python
2404
>>> spam[:5]
2405
'Hello'
2406
```
2407
2408
```python
2409
>>> spam[6:]
2410
'world!'
2411
```
2412
2413
```python
2414
>>> spam[6:-1]
2415
'world'
2416
```
2417
2418
```python
2419
>>> spam[:-1]
2420
'Hello world'
2421
```
2422
2423
```python
2424
>>> spam[::-1]
2425
'!dlrow olleH'
2426
```
2427
2428
```python
2429
>>> spam = 'Hello world!'
2430
>>> fizz = spam[0:5]
2431
>>> fizz
2432
'Hello'
2433
```
2434
2435
[_Return to the Top_](#python-cheatsheet)
2436
2437
### The in and not in Operators with Strings
2438
2439
```python
2440
>>> 'Hello' in 'Hello World'
2441
True
2442
```
2443
2444
```python
2445
>>> 'Hello' in 'Hello'
2446
True
2447
```
2448
2449
```python
2450
>>> 'HELLO' in 'Hello World'
2451
False
2452
```
2453
2454
```python
2455
>>> '' in 'spam'
2456
True
2457
```
2458
2459
```python
2460
>>> 'cats' not in 'cats and dogs'
2461
False
2462
```
2463
2464
### The in and not in Operators with list
2465
2466
```python
2467
>>> a = [1, 2, 3, 4]
2468
>>> 5 in a
2469
False
2470
```
2471
2472
```python
2473
>>> 2 in a
2474
True
2475
```
2476
2477
[_Return to the Top_](#python-cheatsheet)
2478
2479
### The upper(), lower(), isupper(), and islower() String Methods
2480
2481
`upper()` and `lower()`:
2482
2483
```python
2484
>>> spam = 'Hello world!'
2485
>>> spam = spam.upper()
2486
>>> spam
2487
'HELLO WORLD!'
2488
```
2489
2490
```python
2491
>>> spam = spam.lower()
2492
>>> spam
2493
'hello world!'
2494
```
2495
2496
isupper() and islower():
2497
2498
```python
2499
>>> spam = 'Hello world!'
2500
>>> spam.islower()
2501
False
2502
```
2503
2504
```python
2505
>>> spam.isupper()
2506
False
2507
```
2508
2509
```python
2510
>>> 'HELLO'.isupper()
2511
True
2512
```
2513
2514
```python
2515
>>> 'abc12345'.islower()
2516
True
2517
```
2518
2519
```python
2520
>>> '12345'.islower()
2521
False
2522
```
2523
2524
```python
2525
>>> '12345'.isupper()
2526
False
2527
```
2528
2529
[_Return to the Top_](#python-cheatsheet)
2530
2531
### The isX String Methods
2532
2533
- **isalpha()** returns True if the string consists only of letters and is not blank.
2534
- **isalnum()** returns True if the string consists only of letters and numbers and is not blank.
2535
- **isdecimal()** returns True if the string consists only of numeric characters and is not blank.
2536
- **isspace()** returns True if the string consists only of spaces,tabs, and new-lines and is not blank.
2537
- **istitle()** returns True if the string consists only of words that begin with an uppercase letter followed by only lowercase letters.
2538
2539
[_Return to the Top_](#python-cheatsheet)
2540
2541
### The startswith() and endswith() String Methods
2542
2543
```python
2544
>>> 'Hello world!'.startswith('Hello')
2545
True
2546
```
2547
2548
```python
2549
>>> 'Hello world!'.endswith('world!')
2550
True
2551
```
2552
2553
```python
2554
>>> 'abc123'.startswith('abcdef')
2555
False
2556
```
2557
2558
```python
2559
>>> 'abc123'.endswith('12')
2560
False
2561
```
2562
2563
```python
2564
>>> 'Hello world!'.startswith('Hello world!')
2565
True
2566
```
2567
2568
```python
2569
>>> 'Hello world!'.endswith('Hello world!')
2570
True
2571
```
2572
2573
[_Return to the Top_](#python-cheatsheet)
2574
2575
### The join() and split() String Methods
2576
2577
join():
2578
2579
```python
2580
>>> ', '.join(['cats', 'rats', 'bats'])
2581
'cats, rats, bats'
2582
```
2583
2584
```python
2585
>>> ' '.join(['My', 'name', 'is', 'Simon'])
2586
'My name is Simon'
2587
```
2588
2589
```python
2590
>>> 'ABC'.join(['My', 'name', 'is', 'Simon'])
2591
'MyABCnameABCisABCSimon'
2592
```
2593
2594
split():
2595
2596
```python
2597
>>> 'My name is Simon'.split()
2598
['My', 'name', 'is', 'Simon']
2599
```
2600
2601
```python
2602
>>> 'MyABCnameABCisABCSimon'.split('ABC')
2603
['My', 'name', 'is', 'Simon']
2604
```
2605
2606
```python
2607
>>> 'My name is Simon'.split('m')
2608
['My na', 'e is Si', 'on']
2609
```
2610
2611
[_Return to the Top_](#python-cheatsheet)
2612
2613
### Justifying Text with rjust(), ljust(), and center()
2614
2615
rjust() and ljust():
2616
2617
```python
2618
>>> 'Hello'.rjust(10)
2619
' Hello'
2620
```
2621
2622
```python
2623
>>> 'Hello'.rjust(20)
2624
' Hello'
2625
```
2626
2627
```python
2628
>>> 'Hello World'.rjust(20)
2629
' Hello World'
2630
```
2631
2632
```python
2633
>>> 'Hello'.ljust(10)
2634
'Hello '
2635
```
2636
2637
An optional second argument to rjust() and ljust() will specify a fill character other than a space character. Enter the following into the interactive shell:
2638
2639
```python
2640
>>> 'Hello'.rjust(20, '*')
2641
'***************Hello'
2642
```
2643
2644
```python
2645
>>> 'Hello'.ljust(20, '-')
2646
'Hello---------------'
2647
```
2648
2649
center():
2650
2651
```python
2652
>>> 'Hello'.center(20)
2653
' Hello '
2654
```
2655
2656
```python
2657
>>> 'Hello'.center(20, '=')
2658
'=======Hello========'
2659
```
2660
2661
[_Return to the Top_](#python-cheatsheet)
2662
2663
### Removing Whitespace with strip(), rstrip(), and lstrip()
2664
2665
```python
2666
>>> spam = ' Hello World '
2667
>>> spam.strip()
2668
'Hello World'
2669
```
2670
2671
```python
2672
>>> spam.lstrip()
2673
'Hello World '
2674
```
2675
2676
```python
2677
>>> spam.rstrip()
2678
' Hello World'
2679
```
2680
2681
```python
2682
>>> spam = 'SpamSpamBaconSpamEggsSpamSpam'
2683
>>> spam.strip('ampS')
2684
'BaconSpamEggs'
2685
```
2686
2687
[_Return to the Top_](#python-cheatsheet)
2688
2689
### Copying and Pasting Strings with the pyperclip Module (need pip install)
2690
2691
```python
2692
>>> import pyperclip
2693
2694
>>> pyperclip.copy('Hello world!')
2695
2696
>>> pyperclip.paste()
2697
'Hello world!'
2698
```
2699
2700
[_Return to the Top_](#python-cheatsheet)
2701
2702
## String Formatting
2703
2704
### % operator
2705
2706
```python
2707
>>> name = 'Pete'
2708
>>> 'Hello %s' % name
2709
"Hello Pete"
2710
```
2711
2712
We can use the `%x` format specifier to convert an int value to a string:
2713
2714
```python
2715
>>> num = 5
2716
>>> 'I have %x apples' % num
2717
"I have 5 apples"
2718
```
2719
2720
Note: For new code, using [str.format](#string-formatting-strformat) or [f-strings](#formatted-string-literals-or-f-strings-python-36) (Python 3.6+) is strongly recommended over the `%` operator.
2721
2722
[_Return to the Top_](#python-cheatsheet)
2723
2724
### String Formatting (str.format)
2725
2726
Python 3 introduced a new way to do string formatting that was later back-ported to Python 2.7. This makes the syntax for string formatting more regular.
2727
2728
```python
2729
>>> name = 'John'
2730
>>> age = 20'
2731
2732
>>> "Hello I'm {}, my age is {}".format(name, age)
2733
"Hello I'm John, my age is 20"
2734
```
2735
2736
```python
2737
>>> "Hello I'm {0}, my age is {1}".format(name, age)
2738
"Hello I'm John, my age is 20"
2739
```
2740
2741
The official [Python 3.x documentation](https://docs.python.org/3/library/stdtypes.html?highlight=sprintf#printf-style-string-formatting) recommend `str.format` over the `%` operator:
2742
2743
> The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals or the str.format() interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text.
2744
2745
[_Return to the Top_](#python-cheatsheet)
2746
2747
### Lazy string formatting
2748
2749
You would only use `%s` string formatting on functions that can do lazy parameters evaluation,
2750
the most common being logging:
2751
2752
Prefer:
2753
2754
```python
2755
>>> name = "alice"
2756
>>> logging.debug("User name: %s", name)
2757
```
2758
2759
Over:
2760
2761
```python
2762
>>> logging.debug("User name: {}".format(name))
2763
```
2764
2765
Or:
2766
2767
```python
2768
>>> logging.debug("User name: " + name)
2769
```
2770
2771
[_Return to the Top_](#python-cheatsheet)
2772
2773
### Formatted String Literals or f-strings (Python 3.6+)
2774
2775
```python
2776
>>> name = 'Elizabeth'
2777
>>> f'Hello {name}!'
2778
'Hello Elizabeth!
2779
```
2780
2781
It is even possible to do inline arithmetic with it:
2782
2783
```python
2784
>>> a = 5
2785
>>> b = 10
2786
>>> f'Five plus ten is {a + b} and not {2 * (a + b)}.'
2787
'Five plus ten is 15 and not 30.'
2788
```
2789
2790
[_Return to the Top_](#python-cheatsheet)
2791
2792
### Template Strings
2793
2794
A simpler and less powerful mechanism, but it is recommended when handling format strings generated by users. Due to their reduced complexity template strings are a safer choice.
2795
2796
```python
2797
>>> from string import Template
2798
>>> name = 'Elizabeth'
2799
>>> t = Template('Hey $name!')
2800
>>> t.substitute(name=name)
2801
'Hey Elizabeth!'
2802
```
2803
2804
[_Return to the Top_](#python-cheatsheet)
2805
2806
## Regular Expressions
2807
2808
1. Import the regex module with `import re`.
2809
1. Create a Regex object with the `re.compile()` function. (Remember to use a raw string.)
2810
1. Pass the string you want to search into the Regex object’s `search()` method. This returns a `Match` object.
2811
1. Call the Match object’s `group()` method to return a string of the actual matched text.
2812
2813
All the regex functions in Python are in the re module:
>>> mo = phone_num_regex.search('My number is 415-555-4242.')
2840
2841
>>> mo.group(1)
2842
'415'
2843
2844
>>> mo.group(2)
2845
'555-4242'
2846
2847
>>> mo.group(0)
2848
'415-555-4242'
2849
2850
>>> mo.group()
2851
'415-555-4242'
2852
```
2853
2854
To retrieve all the groups at once: use the groups() method—note the plural form for the name.
2855
2856
```python
2857
>>> mo.groups()
2858
('415', '555-4242')
2859
2860
>>> area_code, main_number = mo.groups()
2861
2862
>>> print(area_code)
2863
415
2864
2865
>>> print(main_number)
2866
555-4242
2867
```
2868
2869
[_Return to the Top_](#python-cheatsheet)
2870
2871
### Matching Multiple Groups with the Pipe
2872
2873
The | character is called a pipe. You can use it anywhere you want to match one of many expressions. For example, the regular expression r'Batman|Tina Fey' will match either 'Batman' or 'Tina Fey'.
2874
2875
```python
2876
>>> hero_regex = re.compile (r'Batman|Tina Fey')
2877
2878
>>> mo1 = hero_regex.search('Batman and Tina Fey.')
2879
2880
>>> mo1.group()
2881
'Batman'
2882
2883
>>> mo2 = hero_regex.search('Tina Fey and Batman.')
2884
2885
>>> mo2.group()
2886
'Tina Fey'
2887
```
2888
2889
You can also use the pipe to match one of several patterns as part of your regex:
>>> mo = bat_regex.search('Batmobile lost a wheel')
2895
2896
>>> mo.group()
2897
'Batmobile'
2898
2899
>>> mo.group(1)
2900
'mobile'
2901
```
2902
2903
[_Return to the Top_](#python-cheatsheet)
2904
2905
### Optional Matching with the Question Mark
2906
2907
The ? character flags the group that precedes it as an optional part of the pattern.
2908
2909
```python
2910
>>> bat_regex = re.compile(r'Bat(wo)?man')
2911
>>> mo1 = bat_regex.search('The Adventures of Batman')
2912
>>> mo1.group()
2913
'Batman'
2914
2915
>>> mo2 = bat_regex.search('The Adventures of Batwoman')
2916
>>> mo2.group()
2917
'Batwoman'
2918
```
2919
2920
[_Return to the Top_](#python-cheatsheet)
2921
2922
### Matching Zero or More with the Star
2923
2924
The \* (called the star or asterisk) means “match zero or more”—the group that precedes the star can occur any number of times in the text.
2925
2926
```python
2927
>>> bat_regex = re.compile(r'Bat(wo)*man')
2928
>>> mo1 = bat_regex.search('The Adventures of Batman')
2929
>>> mo1.group()
2930
'Batman'
2931
2932
>>> mo2 = bat_regex.search('The Adventures of Batwoman')
2933
>>> mo2.group()
2934
'Batwoman'
2935
2936
>>> mo3 = bat_regex.search('The Adventures of Batwowowowoman')
2937
>>> mo3.group()
2938
'Batwowowowoman'
2939
```
2940
2941
[_Return to the Top_](#python-cheatsheet)
2942
2943
### Matching One or More with the Plus
2944
2945
While \* means “match zero or more,” the + (or plus) means “match one or more”. The group preceding a plus must appear at least once. It is not optional:
2946
2947
```python
2948
>>> bat_regex = re.compile(r'Bat(wo)+man')
2949
>>> mo1 = bat_regex.search('The Adventures of Batwoman')
2950
>>> mo1.group()
2951
'Batwoman'
2952
```
2953
2954
```python
2955
>>> mo2 = bat_regex.search('The Adventures of Batwowowowoman')
2956
>>> mo2.group()
2957
'Batwowowowoman'
2958
```
2959
2960
```python
2961
>>> mo3 = bat_regex.search('The Adventures of Batman')
2962
>>> mo3 is None
2963
True
2964
```
2965
2966
[_Return to the Top_](#python-cheatsheet)
2967
2968
### Matching Specific Repetitions with Curly Brackets
2969
2970
If you have a group that you want to repeat a specific number of times, follow the group in your regex with a number in curly brackets. For example, the regex (Ha){3} will match the string 'HaHaHa', but it will not match 'HaHa', since the latter has only two repeats of the (Ha) group.
2971
2972
Instead of one number, you can specify a range by writing a minimum, a comma, and a maximum in between the curly brackets. For example, the regex (Ha){3,5} will match 'HaHaHa', 'HaHaHaHa', and 'HaHaHaHaHa'.
2973
2974
```python
2975
>>> ha_regex = re.compile(r'(Ha){3}')
2976
>>> mo1 = ha_regex.search('HaHaHa')
2977
>>> mo1.group()
2978
'HaHaHa'
2979
```
2980
2981
```python
2982
>>> mo2 = ha_regex.search('Ha')
2983
>>> mo2 is None
2984
True
2985
```
2986
2987
[_Return to the Top_](#python-cheatsheet)
2988
2989
### Greedy and Nongreedy Matching
2990
2991
Python’s regular expressions are greedy by default, which means that in ambiguous situations they will match the longest string possible. The non-greedy version of the curly brackets, which matches the shortest string possible, has the closing curly bracket followed by a question mark.
In addition to the search() method, Regex objects also have a findall() method. While search() will return a Match object of the first matched text in the searched string, the findall() method will return the strings of every match in the searched string.
3012
3013
```python
3014
>>> phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # has no groups
To summarize what the findall() method returns, remember the following:
3021
3022
- When called on a regex with no groups, such as \d-\d\d\d-\d\d\d\d, the method findall() returns a list of ng matches, such as ['415-555-9999', '212-555-0000'].
3023
3024
- When called on a regex that has groups, such as (\d\d\d)-(d\d)-(\d\d\d\d), the method findall() returns a list of es of strings (one string for each group), such as [('415', '555', '9999'), ('212', '555', '0000')].
3025
3026
[_Return to the Top_](#python-cheatsheet)
3027
3028
### Making Your Own Character Classes
3029
3030
There are times when you want to match a set of characters but the shorthand character classes (\d, \w, \s, and so on) are too broad. You can define your own character class using square brackets. For example, the character class [aeiouAEIOU] will match any vowel, both lowercase and uppercase.
You can also include ranges of letters or numbers by using a hyphen. For example, the character class [a-zA-Z0-9] will match all lowercase letters, uppercase letters, and numbers.
3040
3041
By placing a caret character (^) just after the character class’s opening bracket, you can make a negative character class. A negative character class will match all the characters that are not in the character class. For example, enter the following into the interactive shell:
- You can also use the caret symbol (^) at the start of a regex to indicate that a match must occur at the beginning of the searched text.
3056
3057
- Likewise, you can put a dollar sign (\$) at the end of the regex to indicate the string must end with this regex pattern.
3058
3059
- And you can use the ^ and \$ together to indicate that the entire string must match the regex—that is, it’s not enough for a match to be made on some subset of the string.
3060
3061
The r'^Hello' regular expression string matches strings that begin with 'Hello':
>>> whole_string_is_num.search('12345xyz67890') is None
3082
True
3083
3084
>>> whole_string_is_num.search('12 34567890') is None
3085
True
3086
```
3087
3088
[_Return to the Top_](#python-cheatsheet)
3089
3090
### The Wildcard Character
3091
3092
The . (or dot) character in a regular expression is called a wildcard and will match any character except for a newline:
3093
3094
```python
3095
>>> at_regex = re.compile(r'.at')
3096
3097
>>> at_regex.findall('The cat in the hat sat on the flat mat.')
3098
['cat', 'hat', 'sat', 'lat', 'mat']
3099
```
3100
3101
[_Return to the Top_](#python-cheatsheet)
3102
3103
### Matching Everything with Dot-Star
3104
3105
```python
3106
>>> name_regex = re.compile(r'First Name: (.*) Last Name: (.*)')
3107
3108
>>> mo = name_regex.search('First Name: Al Last Name: Sweigart')
3109
3110
>>> mo.group(1)
3111
'Al'
3112
```
3113
3114
```python
3115
>>> mo.group(2)
3116
'Sweigart'
3117
```
3118
3119
The dot-star uses greedy mode: It will always try to match as much text as possible. To match any and all text in a nongreedy fashion, use the dot, star, and question mark (.\*?). The question mark tells Python to match in a nongreedy way:
3120
3121
```python
3122
>>> nongreedy_regex = re.compile(r'<.*?>')
3123
>>> mo = nongreedy_regex.search('<To serve man> for dinner.>')
3124
>>> mo.group()
3125
'<To serve man>'
3126
```
3127
3128
```python
3129
>>> greedy_regex = re.compile(r'<.*>')
3130
>>> mo = greedy_regex.search('<To serve man> for dinner.>')
3131
>>> mo.group()
3132
'<To serve man> for dinner.>'
3133
```
3134
3135
[_Return to the Top_](#python-cheatsheet)
3136
3137
### Matching Newlines with the Dot Character
3138
3139
The dot-star will match everything except a newline. By passing re.DOTALL as the second argument to re.compile(), you can make the dot character match all characters, including the newline character:
3140
3141
```python
3142
>>> no_newline_regex = re.compile('.*')
3143
>>> no_newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
3144
'Serve the public trust.'
3145
```
3146
3147
```python
3148
>>> newline_regex = re.compile('.*', re.DOTALL)
3149
>>> newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
3150
'Serve the public trust.\nProtect the innocent.\nUphold the law.'
>>> agent_names_regex.sub(r'\1****', 'Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.')
3222
A**** told C**** that E**** knew B**** was a double agent.'
3223
```
3224
3225
[_Return to the Top_](#python-cheatsheet)
3226
3227
### Managing Complex Regexes
3228
3229
To tell the re.compile() function to ignore whitespace and comments inside the regular expression string, “verbose mode” can be enabled by passing the variable re.VERBOSE as the second argument to re.compile().
3230
3231
Now instead of a hard-to-read regular expression like this:
- An absolute path, which always begins with the root folder
3405
- A relative path, which is relative to the program’s current working directory
3406
3407
There are also the dot (.) and dot-dot (..) folders. These are not real folders but special names that can be used in a path. A single period (“dot”) for a folder name is shorthand for “this directory.” Two periods (“dot-dot”) means “the parent folder.”
3408
3409
[_Return to the Top_](#python-cheatsheet)
3410
3411
### Handling Absolute and Relative Paths
3412
3413
To see if a path is an absolute path:
3414
3415
Using `os.path` on \*nix:
3416
3417
```python
3418
>>> import os
3419
>>> os.path.isabs('/')
3420
True
3421
>>> os.path.isabs('..')
3422
False
3423
```
3424
3425
Using `pathlib` on \*nix:
3426
3427
```python
3428
>>> from pathlib import Path
3429
>>> Path('/').is_absolute()
3430
True
3431
>>> Path('..').is_absolute()
3432
False
3433
```
3434
3435
You can extract an absolute path with both `os.path` and `pathlib`
3436
3437
Using `os.path` on \*nix:
3438
3439
```python
3440
>>> import os
3441
>>> os.getcwd()
3442
'/home/asweigart'
3443
>>> os.path.abspath('..')
3444
'/home'
3445
```
3446
3447
Using `pathlib` on \*nix:
3448
3449
```python
3450
from pathlib import Path
3451
print(Path.cwd())
3452
/home/asweigart
3453
print(Path('..').resolve())
3454
/home
3455
```
3456
3457
You can get a relative path from a starting path to another path.
To read/write to a file in Python, you will want to use the `with`
3772
statement, which will close the file for you after you are done.
3773
3774
[_Return to the Top_](#python-cheatsheet)
3775
3776
### Opening and reading files with the open() function
3777
3778
```python
3779
>>> with open('C:\\Users\\your_home_folder\\hello.txt') as hello_file:
3780
... hello_content = hello_file.read()
3781
>>> hello_content
3782
'Hello World!'
3783
3784
>>> # Alternatively, you can use the *readlines()* method to get a list of string values from the file, one string for each line of text:
3785
3786
>>> with open('sonnet29.txt') as sonnet_file:
3787
... sonnet_file.readlines()
3788
[When, in disgrace with fortune and men's eyes,\n', ' I all alone beweep my
3789
outcast state,\n', And trouble deaf heaven with my bootless cries,\n', And
3790
look upon myself and curse my fate,']
3791
3792
>>> # You can also iterate through the file line by line:
3793
>>> with open('sonnet29.txt') as sonnet_file:
3794
... for line in sonnet_file: # note the new line character will be included in the line
3795
... print(line, end='')
3796
3797
When, in disgrace with fortune and men's eyes,
3798
I all alone beweep my outcast state,
3799
And trouble deaf heaven with my bootless cries,
3800
And look upon myself and curse my fate,
3801
```
3802
3803
[_Return to the Top_](#python-cheatsheet)
3804
3805
### Writing to Files
3806
3807
```python
3808
>>> with open('bacon.txt', 'w') as bacon_file:
3809
... bacon_file.write('Hello world!\n')
3810
13
3811
3812
>>> with open('bacon.txt', 'a') as bacon_file:
3813
... bacon_file.write('Bacon is not a vegetable.')
3814
25
3815
3816
>>> with open('bacon.txt') as bacon_file:
3817
... content = bacon_file.read()
3818
3819
>>> print(content)
3820
Hello world!
3821
Bacon is not a vegetable.
3822
```
3823
3824
[_Return to the Top_](#python-cheatsheet)
3825
3826
### Saving Variables with the shelve Module
3827
3828
To save variables:
3829
3830
```python
3831
>>> import shelve
3832
3833
>>> cats = ['Zophie', 'Pooka', 'Simon']
3834
>>> with shelve.open('mydata') as shelf_file:
3835
... shelf_file['cats'] = cats
3836
```
3837
3838
To open and read variables:
3839
3840
```python
3841
>>> with shelve.open('mydata') as shelf_file:
3842
... print(type(shelf_file))
3843
... print(shelf_file['cats'])
3844
<class 'shelve.DbfilenameShelf'>
3845
['Zophie', 'Pooka', 'Simon']
3846
```
3847
3848
Just like dictionaries, shelf values have keys() and values() methods that will return list-like values of the keys and values in the shelf. Since these methods return list-like values instead of true lists, you should pass them to the list() function to get them in list form.
3849
3850
```python
3851
>>> with shelve.open('mydata') as shelf_file:
3852
... print(list(shelf_file.keys()))
3853
... print(list(shelf_file.values()))
3854
['cats']
3855
[['Zophie', 'Pooka', 'Simon']]
3856
```
3857
3858
[_Return to the Top_](#python-cheatsheet)
3859
3860
### Saving Variables with the pprint.pformat() Function
Install them using `pip install` in your virtual environment.
3971
3972
The first one it easier to use but the second one, Ruamel, implements much better the YAML
3973
specification, and allow for example to modify a YAML content without altering comments.
3974
3975
Open a YAML file with:
3976
3977
```python
3978
from ruamel.yaml import YAML
3979
3980
with open("filename.yaml") as f:
3981
yaml=YAML()
3982
yaml.load(f)
3983
```
3984
3985
[_Return to the Top_](#python-cheatsheet)
3986
3987
### Anyconfig
3988
3989
[Anyconfig](https://pypi.python.org/pypi/anyconfig) is a very handy package allowing to abstract completely the underlying configuration file format. It allows to load a Python dictionary from JSON, YAML, TOML, and so on.
Exceptions are raised with a raise statement. In code, a raise statement consists of the following:
4012
4013
- The raise keyword
4014
- A call to the Exception() function
4015
- A string with a helpful error message passed to the Exception() function
4016
4017
```python
4018
>>> raise Exception('This is the error message.')
4019
Traceback (most recent call last):
4020
File "<pyshell#191>", line 1, in <module>
4021
raise Exception('This is the error message.')
4022
Exception: This is the error message.
4023
```
4024
4025
Often it’s the code that calls the function, not the function itself, that knows how to handle an exception. So you will commonly see a raise statement inside a function and the try and except statements in the code calling the function.
4026
4027
```python
4028
def box_print(symbol, width, height):
4029
if len(symbol) != 1:
4030
raise Exception('Symbol must be a single character string.')
4031
if width <= 2:
4032
raise Exception('Width must be greater than 2.')
4033
if height <= 2:
4034
raise Exception('Height must be greater than 2.')
4035
print(symbol * width)
4036
for i in range(height - 2):
4037
print(symbol + (' ' * (width - 2)) + symbol)
4038
print(symbol * width)
4039
for sym, w, h in (('*', 4, 4), ('O', 20, 5), ('x', 1, 3), ('ZZ', 3, 3)):